You should not capture something weakly just because you get a warning from the compiler; the compiler warning is just guessing; it doesn't know how the methods you call make the references. You should only do this if you understand the architecture of the references and determine that there is a cycle and determine that capturing a weak reference instead still preserves the intended behavior. You haven't shown us the code of -doSomethingWithBlock:
. It would only create a retain cycle if inside that method it assigns the block to a property or instance variable of self
. Does it do that or not? If not, then there is no retain cycle, and there is no point to the outer block capturing self
weakly.
Assuming that the outer block capturing self
weakly is right, the examples where the outer block captures self
strongly are out of the question. The remaining questions would be whether the inner block should capture self
(or whatever version of self
, e.g. strongSelf
, is appropriate) strongly. In other words, whether you would do something like this:
__weak __typeof(self) weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[object doSomethingElseWithBlock:^{
[strongSelf doYetAnotherThing];
}];
}
}];
or something like this:
__weak __typeof(self) weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[object doSomethingElseWithBlock:^{
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doYetAnotherThing];
}
}];
}
}];
Again, the main issue to determine is whether there is a retain cycle if the inner block captures self
strongly. There would only be a retain cycle if [object doSomethingElseWithBlock:...
somehow assigns the block to a property or instance variable of self
. But how could it? The method is called on object
, not self
. The method does not get self
in any way. Unless there is something complicated going on, the method is not going to assign to a property or instance variable of self
, so it is unlikely to create a retain cycle. This means that the inner block capturing self
weakly is not necessary to prevent a retain cycle.
But whether the inner block captures self
weakly or strongly could affect the behavior. Namely, if the inner block captures self
weakly, self
could be deallocated by the time the block is run, in which case [strongSelf doYetAnotherThing];
will not be executed, whereas if the inner block captured self
strongly, it would keep self
alive and [strongSelf doYetAnotherThing];
would be executed. So it depends on what -doYetAnotherThing
does. If it performs some UI operation on self
which is a UI view or something, then whether you perform it on a view that is no longer displayed doesn't make a difference. But if it for example sends something to the network or something, then whether or not it is executed can make a big difference.