完成块在 Swift 3 中变为 nil
Posted
技术标签:
【中文标题】完成块在 Swift 3 中变为 nil【英文标题】:Completion Block becomes nil in Swift 3 【发布时间】:2017-06-21 08:52:36 【问题描述】:我检查了similar question,但在我的情况下出现的问题完全不同。
我使用typealias
来避免重写类似的完成块声明。
typealias FetchFilesCompletionBlock = ( _ files: OPFiles?, _ error: Error?) -> Void
在函数定义中,我使用了FetchFilesCompletionBlock
的可选类型。即使使用完成块调用函数,在函数体中 onCompletion 变为 nil。
func fetchFile(_ param: [String: String]? = nil, onCompletion: FetchFilesCompletionBlock?)
// I found onCompletion is nil here.
// function body
fetchFile(_: onCompletion:)
调用如下:
let onCompletion = (files, error) in
DispatchQueue.main.async(execute: [weak self]() in
self?.onCompletion(files, error: error)
)
as? FetchFilesCompletionBlock
// Here also I found that onCompletion is nil
dataManager.fetchFile(param, onCompletion: onCompletion)
如果我从上面的 sn-p 中删除 as? FetchFilesCompletionBlock
,我会得到一个编译时错误 Cannot convert value of type '(OPFiles?, NSError?) -> ()' to expected argument type 'FetchFilesCompletionBlock?'
。
【问题讨论】:
【参考方案1】:问题是您忘记指定onCompletion
的类型。通过onCompletion
的声明,您还需要指定其类型为FetchFilesCompletionBlock
。
let onCompletion: FetchFilesCompletionBlock = (file, error) in
//Your code
dataManager.fetchFile(param, onCompletion: onCompletion)
【讨论】:
感谢@Nirav,它运作良好。能说说背后的原因吗? @MilanKamilya 欢迎朋友 :),我已经写过您没有在声明中指定onCompletion
的类型,这就是问题所在。
你能告诉我as? FetchFilesCompletionBlock
和let onCompletion: FetchFilesCompletionBlock
有什么区别
@MilanKamilya 带块的类型转换永远不会起作用,所以as? FetchFilesCompletionBlock
总是会失败【参考方案2】:
问题是,在块定义中,您使用 Error 作为错误的类,但在您创建的块中,您使用 NSError 代替,虽然它们是兼容的,但它们不是“隐式”强制转换的,并且按照 Nirav 建议的方式执行“显式地" 铸造了差异(NSError 到 Error)
【讨论】:
没错。感谢@HusseinDimessi 进行深入检查。let onCompletion = (files: OPFiles?, error: Error?) in
- 也出于同样的原因解决了这个问题。
只删除Errors末尾的s?在这里;)但是是的,出于同样的原因,这将解决它以上是关于完成块在 Swift 3 中变为 nil的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3 中使用 prepareForSegue 分配对象变为 nil