2

所以这是我的代码

func retrieveAndAssignHighScoreFromCloudKit() {
    let high = highScore
    database.fetchRecordWithID(getRecordID(high), completionHandler: { [weak self]
        (record: CKRecord?, error: NSError?) in
        if error != nil {
            print(self!.highScore)
        // blah blah blah...
}

所以在这个函数的第一行中,我可以调用 highScore 并将其分配给其他东西,但是在闭包中 Xcode 迫使我使用“self!”。并且这样做会以某种方式打开一个可选项,即使我之前调用它告诉我它不是零。我真的很困惑,有很多关于将可选选项解包为 nil 的基本问题,但我发现没有一个似乎与此有关。

非常感谢!

编辑:尝试将“弱”切换为“无主”,尽管没有断点,但我在同一行崩溃并得到“线程 3:EXC_BREAKPOINT”。此消息在另一个屏幕上以绿色显示,并且不突出显示该行

4

2 回答 2

0

闭包不会立即执行。

当您将闭包传递给该fetchRecordWithID方法时,您是在告诉它在该方法完成获取数据时执行该代码,这可能需要一些时间。

到目前为止一切顺利,对吧?

在闭包的捕获列表中,您告诉它捕获self作为weak参考。这样做的目的是什么?当然是为了避免强引用循环。如果你不这样做,则self持有对闭包的强引用,并且闭包持有对self. 这样一来,既关闭又self不会被取消初始化。

闭包中的weak引用self保证在对闭包self的强引用被破坏时取消初始化。

我希望我已经很好地解释了这一点。

所以现在,假设对闭包的强引用被破坏了。正如我所说,self结果将被取消初始化。之后,这个东西完成了数据的获取,现在它正在执行completionHandler闭包!由于self此时已经为零,因此您的应用程序将在到达时崩溃print(self!.highScore)

换句话说,对的弱引用self意味着self 可以为 nil。你需要打开它。

编辑:

也许图像可以更好地解释这一点。(黑色箭头是强引用,绿色箭头是弱引用)

起初,它是这样的:

在此处输入图像描述

当强引用被破坏时......

在此处输入图像描述

self 变为 nil:

在此处输入图像描述

你可以简单地做这样的事情:

if let score = self?.highScore {
    print(score)
    // blah blah blah
} else {
    // do something else, or nothing
}

或者只是这样:

print(self?.highScore)
于 2016-08-09T03:38:44.147 回答
-1

您可以strong在尝试self像这样使用时使用参考:

func retrieveAndAssignHighScoreFromCloudKit() {
        let high = highScore
        database.fetchRecordWithID(getRecordID(high), completionHandler: { [weak self]
            (record: CKRecord?, error: NSError?) in
            if error != nil {
                
                guard let strongSelf = self else {
                    return
                }
                print(strongSelf.highScore)
                // blah blah blah...
            }
        }
    }
于 2016-08-09T06:54:20.447 回答