我读了以下article,但我对以下段落感到困惑。
Apple文档说“然而,对于非平凡的周期,你应该使用”这种方法:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler = ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
// ...
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// ...
}
else {
// Probably nothing...
}
};
首先,这个例子对我来说是错误的。自我怎么样? 如果块本身保留在块中,则取消分配并填空 completionHandler属性? completionHandler属性可以是 声明为assign或unsafe_unretained以允许该对象 在块被传递之后解除分配。我看不出原因 这样做。如果其他对象需要对象(self),则为块 传递的应该保留对象,因此保留块 不应该分配给一个属性。没有_ 弱/ _strong用法应该 参与此案。
他说“如果其他物品需要物体(自我):” 这里的需求是什么意思?它是这样的:他们需要自我,因为他们访问需要自我的块(传递给他们的块),所以他们需要自我。如果不是他的意思?
然后他说“因此不应该将区块分配给一个房产。” 但是,如果将来有多个对象需要块一些未定义的时间呢?所以,我们可以通过从这个属性获取块来传递它们。
我采取了错误的方式吗?
答案 0 :(得分:3)
该文章的作者有点困惑,并且有些事情倒退了。
如果块本身是自我,那么如何自我解除分配并被填空 保留在completionHandler属性中?
如果该块保留在completionHandler
中,则表示self
具有对该块的强引用,这意味着只要self
是块,该块就是活动的 - 不是其他方式。 self
保留该块与self
被解除分配无关。
completionHandler属性可以声明为assign或 unsafe_unretained允许对象在之后被释放 块被传递。
同样,completionHandler
是强引用还是弱引用会影响块的生命周期。它与self
生命周期所指向的对象无关。
如果其他对象需要对象(self),则传递的块 周围应该保留对象,因此块不应该 分配给一个财产。
没有。该对象保留该块。该块不保留该对象。
在大多数情况下是否需要代码示例中显示的模式是非常值得商榷的。但是,作者的推理是错误的。
答案 1 :(得分:0)
Blocks保留其中提到的变量,以便它们可以在它们首次出现的上下文中执行。当其中一个保留的块变量直接(平凡)或间接(非平凡)保留块时,您会得到一个循环。
例如,当objectA拥有一个提到objectA的块时,我们得到一个简单的循环:objectA - >块 - >对象A
// objectA owns a block property (declared as copy) called theBlock
objectA.theBlock = ^{
// anything in the current scope can be mentioned safely in here, except:
[objectA doSomething];
};
该文章的建议应该是通过在块中使用objectA指针的未保留副本来打破保留周期...
__unsafe_unretained ObjectAType *objectAUnretainedCopy = objectA;
// in an ARC project, @Rob points out that this is probably better qualified as __weak
objectA.theBlock = ^{
// now we can mention anything in the current scope, including:
[objectAUnretainedCopy doSomething];
};
现在objectA仍然保留了块,但是这个改进的块不会保留objectA。
一个非平凡的周期是相同的,只是拥有更长的所有权链,使得周期更难以识别。假设objectB保留一个保留(强)指向objectA ...
的指针objectB.myObjectA = objectA;
现在在objectA的块中提到objectB是错误的,因为你最终得到了一个循环: objectB - > objectA - > theBlock - >对象B
objectA.theBlock = ^{
// anything in the current scope can be mentioned safely in here, except:
[objectB doSomething];
};
同样的解决方案适用。不要直接引用objectB,而是使用未保留的副本......
__unsafe_unretained ObjectBType *objectBUnretainedCopy = objectB;
// again, per @Rob, or __weak
答案 2 :(得分:0)
请参考以下博客,这是有道理的。它以更好的方式解释它。
https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/