在 dispatch_async 中调用委托方法

Posted

技术标签:

【中文标题】在 dispatch_async 中调用委托方法【英文标题】:Calling a delegate method in dispatch_async 【发布时间】:2014-06-25 07:31:44 【问题描述】:

我已经实现了一个简单的委托模式,我需要在主队列中调用委托方法。这是执行此调用的代码:

dispatch_async(dispatch_get_main_queue())
    self.delegate?.readerDidCompleteDownload(self, data: tempData)
 

但是因为这个错误我无法编译

Could not find member: readerDidCompleteDownload:

方法在委托中实现并且协议正确定义了它

@objc protocol DBDataReaderDelegate
    func readerDidCompleteDownload(reader: DBDataReader, data:String[])
    
    @optional func readerDidFailDownload(reader: DBDataReader)

如果我在dispatch_async 之外调用此方法,它可以正常工作。

我做错了什么?!

编辑

我在 NSURLSessionDownloadDelegate 函数中调用这个方法...我在这里报告完整代码只是为了向这个问题添加更多信息:

func URLSession(session: NSURLSession!, downloadTask: NSURLSessionDownloadTask!, didFinishDownloadingToURL location: NSURL!)
    
    let data = NSData(contentsOfURL: location)
    var error:NSError
    let string = NSString(data: data, encoding: NSUTF8StringEncoding)
    
    if let JSONObj:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? NSDictionary 
        var tempData:String[] = String[]()
        
        if let shots = JSONObj["shots"] as? NSDictionary[]
            
            for (index, element) in enumerate(shots)
                
                if let title:String = element["title"] as? String
                    tempData += title
                
            
            
            dispatch_async(dispatch_get_main_queue())
                self.delegate?.readerDidCompleteDownload(self, data: tempData)
            
        
    else
        delegate?.readerDidFailDownload?(self)
    

【问题讨论】:

【参考方案1】:
„The type of this function is () -> (), or “a function that has no parameters, 
 and returns Void.” Functions that don’t specify a return value always 
 return Void, which is equivalent to an empty tuple in Swift, shown as ().” 

 Apple Inc. „The Swift Programming Language”. iBooks

由于delegate是可选类型,可以为nil,而且Swift中的每个函数或方法都必须有返回值,例如Void!、(),所以只需要在dispatch_async末尾加上元组()就可以了

dispatch_async(dispatch_get_main_queue())
    self.delegate?.readerDidCompleteDownload(self, data: tempData)
    ()

【讨论】:

我不工作。我收到此错误:Invalid use of '()' to call a value of non function type '()' pastebin.com/DXM4sRdY - 将它粘贴到操场上,看看一切都很好 对不起,我在函数调用之后添加了括号。是的!它有效......但我真的明白为什么。返回“void”不只是说返回“nothing”? „这个函数的类型是 () -> (),或者“一个没有参数,返回 Void 的函数”。不指定返回值的函数总是返回 Void,相当于 Swift 中的一个空元组,显示为 ()。”苹果公司“Swift 编程语言”。 iBooks。 您可以将 () 替换为普通的旧 return 来验证这一点。哪种风格在 swift 世界中最流行尚未明确,出于清楚的原因,我稍微在回归阵营。【参考方案2】:
dispatch_async(dispatch_get_main_queue())  () -> Void in
    self.delegate?.readerDidCompleteDownload(self, data: tempData)

没有() -> Void in,Swift 会推断闭包的类型。推断结果来自“optional chaining”readerDidCompleteDownload,所以是Void?。这使得推断的闭包类型 () -> Void?(可选 Void)与 dispatch_block_t 不同:() -> Void(非可选 Void)。

这可能会在 Swift 中使用一些语法糖。

【讨论】:

以上是关于在 dispatch_async 中调用委托方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在目标 c 中使用 GCD dispatch_async 调用/编写以下方法

Runloop 不处理来自 dispatch_async 的事件

未调用 CLLocation Manager didStartMonitoringForRegion 委托方法

未调用 mkmapview 委托方法 -calloutaccessorycontroltapped

4.1.1委托和广播

如何以 Fire-And-Forget 的形式调用委托调用