Swift弱的懒惰变量不会编译

LSh*_*Shi 11 cocoa weak-references lazy-evaluation swift

为了证明这个问题,我做了一个vanilla Cocoa项目.这是AppDelegate.swift:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    weak lazy var isGood : NSNumber? = {
        return true
    }()

    func doSomething() {
        let result = isGood!
    }

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }
}
Run Code Online (Sandbox Code Playgroud)

Xcode给出了这个:

unkown:0:错误:无法转换类型'NSNumber?'的返回表达式 (又名"可选")返回类型'NSNumber?'

unkown:0:不能指定'NSNumber?'类型的值?输入'NSNumber ??'

unkown:0:不能指定'NSNumber?'类型的值?输入'NSNumber ??'

在我的实际项目中,它是MyCustomClass(而不是NSNumber)的另一个对象.除类型外,错误相同MyCustomClass.

如果我删除weaklazy从声明中删除,一切都很好.但我想从被+1保存引用计数,因为MyCustomClassNSViewController这是一定要永远存在.

知道如何使用弱懒变量吗?

das*_*ght 28

弱和懒惰混合不好.该错误信息是完全无用的解释是怎么回事,但本质上lazyweak处于相互矛盾:

  • lazy 告诉Swift你不希望你的变量在你第一次访问它时被创建,但是一旦创建它,​​你想要无限期地保存它以供将来参考,同时
  • weak告诉Swift你不希望你的变量成为保持变量被释放的最后一个链接,这对lazy变量的"保持无限"目标是有效的.

您可以通过仿真来解决这个问题lazy,如下所示:

class Foo {

    weak var isGoodCache : NSNumber?

    private var makeIsGood : NSNumber {
        isGoodCache = true
        return isGoodCache!
    }

    var isGood:NSNumber? {
        return isGoodCache ?? makeIsGood
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 太棒了!这正是我所寻找的.但我开始思考我是否过度工程化.一个保留不会伤害,对吧?这里唯一的好处可能是它可以防止将来可能的参考周期. (2认同)

Ala*_* T. 7

懒惰和弱不兼容的原因是每次使用都会创建一个新实例,除非你有另一个拥有强引用的地方.如果您有另一个地方来保存强引用,那么您不需要您的类成员是创建实例的类成员.

让我们假设我们:

weak lazy var myVariable: MyClass? = createMyClassInstance()
Run Code Online (Sandbox Code Playgroud)

当你第一次使用它时,让我们说你只是在某个函数调用中引用它...

myFunction(myVariable)
Run Code Online (Sandbox Code Playgroud)

在下一行,myVariable再次为空.

这是为什么?因为,一旦myFunction完成,就不再有对myVariable的引用了,因为它很弱,相应的对象超出了范围而消失了.

惰性弱变量和任何函数调用结果之间没有区别.因此,您的变量也可以是函数或计算变量(这会使任何查看代码的人更清楚).