I thought I understood the usage of self in a block that is copied is a no no.
But in an attempt to clean my code i enabled a bunch of warnings in Xcode, one called "Sending messages to weak pointers"
so now in all my blocks, every time I use my created weakself
reference __weak typeof(self) weakself = self;
I get this warning: Weak receiver may be unpredictably set to nil
a trivial example:
__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
[weakself doSomething]; //warning.
}];
I have seen answers which define a version of self within the block like so:
__weak typeof(self) weakself = self;
[aClass doSomethingInABlock:^{
typeof(self) selfref = weakself;
[selfref doSomething]; //no warning.
}];
So I'm wondering what actually happens here:
- Am I just tricking the compiler?
- what does a strong reference to a weak reference do?
- anything else I'm missing.
Thanks.
This is not strictly correct. Blocks retain the objects in them, so don't use
self
in a block if your block is retained byself
.For example, you can use
self
just fine in a UIView animation block. This is because your view controller (or whatever code is calling the animation) doesn't have a pointer to the UIView animation block.)No.
If the weak reference is not
nil
, the retain count of the receiver is increased. This will stop the object from being deallocated while you're using it.Remember, ARC will deallocate objects when there are no longer strong references to them. By creating a strong reference inside the block, you're preventing possible deallocation until you're done with it.
I recommend reading the Practical Memory Management section of the Advanced Memory Management Programming Guide. Especially, read the subsection "Use Weak References to Avoid Retain Cycles".
Remember that in ARC, an object will not be deallocated as long as there's a strong reference to it.
When an object has a weak reference, the object might be deallocated (if there's no other strong reference to the same object), so a weak reference doesn't ensure the objects life.
By doing this:
you're ensuring that you have a strong reference to that object before you use it (
selfref
is the strong reference pointing to the same objectweakself
is referring to). If you don't do this, the object could be deallocated while you use it.Strong reference to a weak reference retains an object. It could be important in following case
If Weak receiver will be unpredictably set to nil in line (2) resources could be successfully allocated in (1) but not freed in (3). To avoid such problems strong reference could be used.
Now if selfref is not nil in (1) it will also be valid in (2) and (3).