简体   繁体   中英

Calling a delegate method in dispatch_async

I've implemented a simple delegate pattern and I need to call delegate methods in the main queue. This is the code that perform this call:

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

but I can't compile because of this error

Could not find member: readerDidCompleteDownload:

The method is implemented in the delegate and the protocol correctly defines it

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

    @optional func readerDidFailDownload(reader: DBDataReader)
}

If I call this method outside the dispatch_async it works correctly.

What I'm doing wrong?!

Edit

I'm calling this method in NSURLSessionDownloadDelegate function... I report here the full code just to add more information to this question:

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)
    }
}
„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

Because delegate is optional type and can be nil, and every function or method in Swift must return value, for example Void!, (), you just need to add tuple () at the end of dispatch_async

dispatch_async(dispatch_get_main_queue()){
    self.delegate?.readerDidCompleteDownload(self, data: tempData)
    ()
}
dispatch_async(dispatch_get_main_queue()) { () -> Void in
    self.delegate?.readerDidCompleteDownload(self, data: tempData)
}

Without () -> Void in , Swift infers the type of the closure. The inferred result comes from " optional chaining " readerDidCompleteDownload , so it is Void? . That makes the inferred closure type () -> Void? (optional Void) which is not the same as what dispatch_block_t is: () -> Void (non-optional Void).

This could use some syntactic sugar in Swift.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM