swift闭包存储和作为变量访问

ale*_*lex 4 variables closures callback swift

我想在swift项目中实现一个回调,就像我以前在Objective-C中做的一样,我需要一个类型为closure的变量.该闭包应该作为参数作为对象并且不返回任何内容.

var downloadCompleted: (MLBook) -> (Void)!
Run Code Online (Sandbox Code Playgroud)

当我需要触发回调时,我这样做:

if self.downloadCompleted {
   self.downloadCompleted(book)
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨此错误消息:

 Type '(MLBook) -> (Void)!' does not conform to protocol 'BooleanType'
Run Code Online (Sandbox Code Playgroud)

如果删除if语句,编译器会说:

Property 'self.downloadCompleted' not initialized
Run Code Online (Sandbox Code Playgroud)

即使它被隐含地打开了.

当我尝试获得回调时:

BookStore.sharedInstance.downloadCompleted{(book: MLBook) -> () in
   println("Print if you got the callback")
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息:

'(MLBook) -> ()' is not convertible to 'MLBook'
Run Code Online (Sandbox Code Playgroud)

我更担心最后一条错误消息,因为我不太确定它要告诉我什么.

任何帮助,将不胜感激.谢谢

GoZ*_*ner 6

这是你的工作实例.你有很多错误,附带说明.注意我有download()方法返回,Bool以便在此屏幕截图中看到结果.

在此输入图像描述

但是,您使用隐式展开的可选(也称为"!")是不正确的.当值可能nil但将在已知时间分配并且未更改时,将使用此类可选项(有关说明,请参阅Apple文档).你downloadCompleted是一个真正的选择(至少在你的例子中使用).因此,更好的代码,结果稍微简单:

在此输入图像描述


Shu*_*huo 5

2个错误。1、整个类型应该用 () 包裹起来,然后跟一个 ? 或者 !作为可选或隐式解包可选。第二,你应该检查 nil,在 swift 中,没有隐式布尔转换。

在您的用例中,您应该使用可选而不是隐式解包。因为你的财产很可能为零价值。使用 IUO(隐式解包可选),您可以跳过编译器警告并会收到运行时错误。

import Foundation

class MLBook {
    var name = "name"
}

class A {
    var downloadCompleted: ((MLBook) -> Void)?

    func down(){
        var book = MLBook()
        if let cb = self.downloadCompleted {
            cb(book)
        }
    }  
}

var a = A()
a.downloadCompleted = {
    (book: MLBook) -> Void in
    println(book.name)
}

a.down()
Run Code Online (Sandbox Code Playgroud)