Calling function in block retain cycle
-
02-07-2021 - |
Pergunta
If a function I called from inside a block references 'self', would that create a retain cycle?
__weak id weakSelf = self;
- (void)firstFunction
{
id strongSelf = weakSelf;
if (!strongSelf) return;
[anObject performBlock:^{
[strongSelf secondFunction];
}];
}
- (void)secondFunction
{
[self doSomeCrazyStuff];
self.counter++;
//etc.
}
I'm calling 'self' in 'secondFunction', do I need to pass my weak pointer into this function and use it instead?
Solução
Potentially.
A retain cycle is created by having a cycle of strong references, apart from the qualifier (i.e. weak, strong) on the variable the actual variables where those references come from is irrelevant. So strongSelf
referenced by your block is a strong reference to self
and you have the same potential for a retain cycle as if you'd used self
itself.
Re: comment
Having your block maintain a weak reference is the standard approach to addressing this issue. If you use weakSelf
in your block then there is no strong reference, if by the time the block is called weakSelf
is nil
then the call [weakSelf secondFunction]
will do nothing - you are allowed to message nil
in Objective-C. You won't create a cycle, during the call of the block a strong copy of the reference may be created but this will go after the call to the block returns.
Outras dicas
I could be wrong but I see no retain cycle here.
Blocks are stack allocated unless they are copied to the heap.
I dont use ARC so your mileage may vary, but at least without ARC I would have no expectation of a retain cycle when the block is stack allocated and it has no retained reference to self.
The reference to self will be copied to the blocks stack and if it goes out of scope the block will continue to access the copy until the block terminates.
I dont assume to know how ARC manages this, I figure if you are going to use ARC you should know yourself how it works.
But as far as non ARC code is concerned, I see no retain cycle in this code whatsoever.