weak-strong dance 用来解决循环引用问题
参考
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW22
https://developer.apple.com/videos/play/wwdc2011/322/
https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4
(Use Lifetime Qualifiers to Avoid Strong Reference Cycles)
It’s also important to consider the implications of a method that needs to access a weak property several times, like this:
有必要考虑那些需要多次访问weak属性的方法所受到的潜在影响,如下
- (void)someMethod { |
[self.weakProperty doSomething]; |
... |
[self.weakProperty doSomethingElse]; |
} |
In situations like this, you might want to cache the weak property in a strong variable to ensure that it is kept in memory as long as you need to use it:
像这种情况,你也许想将weak属性缓存下来,并将它保存在内存中直到你不再使用它
- (void)someMethod { |
NSObject *cachedObject = self.weakProperty; |
[cachedObject doSomething]; |
... |
[cachedObject doSomethingElse]; |
} |
In this example, the cachedObject
variable maintains a strong reference to the original weak property value so that it can’t be deallocated as long ascachedObject
is still in scope (and hasn’t been reassigned another value).
在这个例子中,cacheObject变量保持了一个队原始weak属性值的强引用,所以在作用域内它不会被析构(没有被赋予其它的值)。
It’s particularly important to keep this in mind if you need to make sure a weak property is not nil
before using it. It’s not enough just to test it, like this:
时刻谨记如果你需要保证weak属性值在使用前不为nil,就需要按上面的做。仅仅判断它是否为nil是不足够的。
if (self.someWeakProperty) { |
[someObject doSomethingImportantWith:self.someWeakProperty]; |
} |
because in a multi-threaded application, the property may be deallocated between the test and the method call, rendering the test useless. Instead, you need to declare a strong local variable to cache the value, like this:
因为在多线程程序中,这个属性值很有可能在判断是否为空(第2行)和方法调用(第3行)之间被执行了析构操作,最终导致了无效的判断。
你可以按下面这样,先声明一个强引用变量来存储weak属性的值
NSObject *cachedObject = self.someWeakProperty; // 1 |
if (cachedObject) { // 2 |
[someObject doSomethingImportantWith:cachedObject]; // 3 |
} // 4 |
cachedObject = nil; // 5 |
In this example, the strong reference is created in line 1, meaning that the object is guaranteed to be alive for the test and method call. In line 5, cachedObject
is set to nil
, thereby giving up the strong reference. If the original object has no other strong references to it at this point, it will be deallocated andsomeWeakProperty
will be set to nil
.
在这个例子中,第1行创建了一个强引用,意味着这个对象保证了在判断和方法调用期间都是可用的(不为nil).第5行,将cachedObject置为了nil,放弃了强引用。如果此时没有其他的强引用指向原来的对象,它将会被析构,并且someWeakProperty被置为nil