当我必须在一个区块中引用self时,我最近学会了这个技巧。
__weak MyObject *safeSelf = self;
[self doWithCompletionBlock:^{
HMFInventoryBatchItemsController *strongSelf = safeSelf;
if (strongSelf) {
[strongSelf doSomethingElse];
}
}];
但我一直想知道,如果我在一个街区内有一个街区怎么办?我是否需要再次做同样的事情?
__weak MyObject *safeSelf = self;
[self doWithCompletionBlock:^{
HMFInventoryBatchItemsController *strongSelf = safeSelf;
if (strongSelf) {
__weak MyObject *saferSelf = strongSelf;
[strongSelf doAnotherThingWithCompletionBlock:^{
HMFInventoryBatchItemsController *strongerSelf = saferSelf;
if (strongerSelf) {
[strongerSelf doSomethingElse];
}
}];
}
}];
或者这很好
__weak MyObject *safeSelf = self;
[self doWithCompletionBlock:^{
HMFInventoryBatchItemsController *strongSelf = safeSelf;
if (strongSelf) {
[strongSelf doAnotherThingWithCompletionBlock:^{
[strongSelf doSomethingElse];
}];
}
}];
答案 0 :(得分:2)
好的答案是,这取决于。这通常是不安全的:
__weak MyObject *safeSelf = self;
[self doWithCompletionBlock:^{
[safeSelf doAnotherThingWithCompletionBlock:^{
[safeSelf doSomethingElse];
}];
}];
原因在于,当你调用-doAnotherThingWithCompletionBlock
时,如果该方法认为它会在self
上保留一个引用,这是一个选择器通常会假设的,并且它会自我解除引用要访问ivars,那么你会崩溃,因为你实际上没有持有引用。
因此,您是否需要采用新的弱引用取决于您需要/想要的生命周期语义。
修改强>
顺便说一句,clang甚至会警告您可以在Xcode中使用CLANG_WARN_OBJC_RECEIVER_WEAK
设置启用该问题(CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK
在我们使用时也很有用)
答案 1 :(得分:0)
__block MyObject *safeSelf = self;
[self doWithCompletionBlock:^{
[safeSelf doAnotherThingWithCompletionBlock:^{
[safeSelf doSomethingElse];
}];
}];
希望它会做它应该做的事情。告诉编译器不要保留__weak MyObject *,无论它在哪个块范围内。事实是我没有经过测试。同时,如果它真的会保留MyObject *,我会感到惊讶。