【问题标题】:Structure function with async closure variable具有异步闭包变量的结构函数
【发布时间】:2016-04-02 21:30:13
【问题描述】:

我正在尝试做某事可能很奇怪,但我遇到了以下问题。

我有一个带有闭包属性的结构,我设置了异步函数。

我想要的是,调用这个异步函数来获取返回值。

我可以通过变通解决方案来解决这个问题,但我想用正确的方法来解决这个问题。

感谢任何帮助。

这是我的代码:

struct Item {
  var myselector: (String -> Void)?
  func getMeThat(completion: String -> Void) {
    completion(myselector()) // error: cannot call value of non-function type String -> Void
  }
}

class API {
  class func requestThing(completion: String -> Void) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
      completion("Kenan")
    })
  }
}

class ViewController {
  func viewDidLoad() {
    var item = Item()
    item.myselector = { // error: cannot assign value of type () -> () to type String -> Void
      API.requestThing({ (str: String) in
        <#code#>
      })
    }
    item.getMeThat({ (rtn: String) in
      print(rtn)
    })
  }
}

【问题讨论】:

  • 您能否将错误消息直接编辑到您的问题中而不是屏幕截图中?

标签: ios swift asynchronous closures


【解决方案1】:

主要问题是由于奇怪的重复而导致您的签名未匹配。

您正在将闭包设置为结构的变量,但也为函数提供了完成。做一个或另一个。

struct Item {
    func getMeThat(completion: String -> Void) {
        API.requestThing(completion)
    }
}

class API {
    class func requestThing(completion: String -> Void) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
            completion("Kenan")
        })
    }
}

class ViewController {
    func viewDidLoad() {
        let item = Item()
        item.getMeThat({ (rtn: String) in
            print(rtn)
        })
    }
}

如果你只是想延迟代码的执行,这就是你的做法

struct Item {
    var myselector: (Void -> Void)?
    func executeSelector() {
        guard let sel = myselector else {
            return
        }

        sel()
    }
}

class API {
    class func requestThing(completion: String -> Void) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
            completion("Kenan")
        })
    }
}

class ViewController {
    func viewDidLoad() {
        var item = Item()
        item.myselector = {
            API.requestThing({ (str: String) in
                print(str)
            })
        }
        item.executeSelector()
    }
}

【讨论】:

  • 感谢您的回答。你是对的,但我想将函数设置为变量并在其他地方调用它。如果函数不必是异步的,它将适用于这种架构。
  • 我看不出异步是如何出现问题的,您需要在闭包中捕获异步调用返回时仍需要存在的项目。闭包最终被 dispatch_after 闭包捕获,因此它在那个时刻仍然存在,它本身捕获的所有内容。
  • 是的。你的第二个答案正是我想要的。非常感谢您的努力。
猜你喜欢
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多