Using self.
in blocks causes retain cycles, so I need to create a reference to weakSelf
. I understand this
BUT!
If from my block I
I might be misreading your question, but your wording:
If from my block I call a method which uses "self.", does this too cause a retain cycle? For instance if I reload a UITableView from a block and in some of my UITableView delegates I call "self.", I'm causing a retain cycle? That means I have to pass around this weakReference everywhere?
suggests you are misunderstanding what self
is. Hopefully if so the following will help and not hinder your understanding...
What is self
?
The identifier self
is just the name of one of the parameters to your method, it is just passed implicitly rather then explicitly like the other parameters. For example if you have a class:
@implementation MyClass
- (void) someMethod:(NSInteger)value
{
... self ... value
}
@end
then the method is effectively (i.e. bending the facts just a little for clarity):
- (void) someMethod:(NSInteger)value withObject:(MyClass *)self
{
... self ... value
}
When an instance method is called the value passed for the self
parameter is a reference to the instance the method should operate on, e.g. the call
MyClass *someInstance = ...
[someInstance someMethod:42];
is effectively a call to:
someMethod:42 withObject:someInstance
Strong reference cycles
An object - which includes both instances of classes and blocks - is kept alive as long as there exists a strong reference to the object.
If an object A
holds a strong references, e.g. in an instance variable or property, to an object B
, then B
will be kept alive at least (there could be other strong references to B
) as long as A
is alive.
If an object A
holds a strong reference to B
and B
holds one to A
then you have a strong reference cycle - each object is keeping the other alive and neither will ever be collected. This could lead to a memory leak - where unused memory is never collected - unless both A
and B
are meant to live from creation till the end of the program.
Further, you do not create a strong reference cycle simply by having references stored in the local variables and parameters of methods. By their nature such variables, and therefore their contents, are transient and are destroyed when the method returns.
Using self
in blocks
using "self." in blocks causes retain cycles so I need to create a reference to weakSelf.
Not quite. When you use self
in a block, either directly or indirectly by referencing an instance variable, then the compiler will warn you that you may create a reference cycle.
(Note: There are other ways to create reference cycles, both with and without using blocks, and the compiler will not warn you at all. Managing cycles is just something you need to be aware of.)
You will only actually create a cycle if you store a reference to the block in the object referenced by self
. However this is not bad in itself, as long as at some point you break the cycle manually - say by storing nil
in the variable referencing the block - the cycle need not be problematic at all.
Finally...
You have nothing per se to worry about with your:
UITableView delegates I call "self."
as that self
is just a local parameter to the delegate whose initial value, at some point going back up the call chain, came from you evaluating your weakSelf
reference and determining that it was not nil
and then calling methods on it.
HTH