Let's say I'm trying to access self
from within a block:
[someObject successBlock:^(NSArray *result) {
[self someSuccessMethod];
} failure:^(NSString *errorMessage, int status) {
[self someFailureMethod];
}];
I understand that this creates a retain cycle and that someObject
and self
never get de-alloced.
What's confusing me is what actually happens with/without the __block
keyword. I can fix the retain cycle by making a __weak
reference to self:
__weak MyClass* me = self;
[someObject successBlock:^(NSArray *result) {
[me someSuccessMethod];
} failure:^(NSString *errorMessage, int status) {
[me someFailureMethod];
}];
I don't need to use __block
here, because I'm not trying to modify me
from within the block. From what I understand, if I don't use __block
, a copy of me
is referenced inside the block. My question is: if what's being referenced inside the block is just a copy of the object, why does the original code block create the retain cycle? I would guess that the reference to self
is just a copy, since I'm never using the __block
keyword. Am I thinking about this incorrectly?
In the first case, the block captures self
, i.e. it saves a copy of self
as another strong pointer. That increases the retain count of the pointed-to object, and causes the retain cycle.
In the second case, the block captures me
, i.e. it saves a copy of me
as another weak
pointer. That does not increase the retain count and therefore causes no retain cycles.
(If you print the address of me
outside and inside the block, you will see that
the addresses are different. The block has its own weak pointer to the object.)
If the pointed-to object is deallocated, all weak references (including the one saved by
the block) are set to nil
by the Objective-C runtime.
(I just hope that I got this right.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With