具有计算属性的弱关键字

时间:2016-08-10 12:44:28

标签: swift

private weak var _delegate: SomeClassDelegate?
weak var delegate: SomeClassDelegate? {
    get {
        return _delegate
    }
    set {
        _delegate = newValue
    }
}

这是有效的代码。将weak关键字与计算delegate属性一起使用是否有任何意义?逻辑上没有;编译器将如何处理此代码?

2 个答案:

答案 0 :(得分:2)

  

weak关键字与计算的委托属性一起使用是否有意义?

这样做不仅明智,而且非常重要。此计算的属性是此私有隐藏属性的公共接口。如果计算出的属性缺少weak限定符,则调用者将得出有关底层语义的错误结论。

考虑:

class SomeClass {
    private weak var _delegate: SomeClassDelegate?
    var delegate: SomeClassDelegate? {             // whoops; this should be `weak`
        get { return _delegate }
        set { _delegate = newValue }
    }
}

class CustomDelegate: SomeClassDelegate { ... }

然后

let object = SomeClass()
object.delegate = CustomDelegate()

在计算属性上没有weak限定符的情况下,如果不深入研究实现细节,程序员可能会错误地得出上述结论是正确的。但事实并非如此。由于基础_delegateweak,因此该CustomDelegate()实例将立即被释放,并且该对象最终将没有委托对象。并且没有编译器警告有关此行为。

但是,如果我们像这样修复SomeClass

class SomeClass {
    private weak var _delegate: SomeClassDelegate?
    weak var delegate: SomeClassDelegate? {        // great; matches underlying semantics
        get { return _delegate }
        set { _delegate = newValue }
    }
}

然后程序员将收到一个非常有用的警告:

let object = SomeClass()
object.delegate = CustomDelegate()  // results in "Instance will be immediately deallocated because property 'delegate' is 'weak'"

然后他们会正确推断出,他们应该对此CustomDelegate保持强烈的引用,以使代码正常工作。

因此,最重要的是,从技术上讲,您不需要在由私有weak存储的私有属性支持的计算属性上的weak限定符,但为避免神秘的错误和/或对基本语义的误解。

答案 1 :(得分:1)

ARC不会保留计算属性,因此您无需将其标记为弱。

我所知道的只有一位专业人士将来确保财产可能为零。您不能将其声明为:

weak var youProperty: YourType { 
    get {
        return _yourProperty
    } 
    set { 
        _yourProperty = newValue
    }
}