Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WeakSelf in blocks

Got a question about weak self , blocks and retain cycle.

By the book i understand we need to use weakself in blocks.. The question is , when ?

for example, simple animation code, never contain weakself..

i.e

self.myView.alpha = 1.0;
[UIView animateWithDuration:0.2 animations:^{
self.myView.alpha = 1.0; 
}];

is this code ok ? or should i create a weakself before the block and use it inside ?

In all my code and all other projects i ever worked on, never saw a single line that uses weak self. i'm now trying to use weakself in every block.. it's just that i'm not sure it's necessary

Looking forward for your opinions Thanks

like image 621
ibm123 Avatar asked Dec 20 '22 16:12

ibm123


2 Answers

You should use weak selfs when there is a possibility of retain cycles.

Imagine an instance of foo has a strong reference to bar. Now you give bar a block with references to foo's self. Now someone releases foo, but bar has kept the block around. Now foo has a strong reference to bar and bar holds a strong reference to foo in the block. Foo will not be released, and therefore also bar, as bar is holding on to it. But the only thing holding on to bar is the now unused foo. You've got yourself a retain cycle, and the two objects are now floating in memory unable to be reached.

UIView's animations pose no problem, as the block is called before the animate: method returns, and UIView does not keep the block around.

ARC will usually warn you whenever it sees the possibility of a retain cycle. But that's not always the case. A good rule of thumb is to use weak selfs whenever you don't know where the block will en up.

Hope this is a bit of help.

like image 54
Trenskow Avatar answered Jan 15 '23 00:01

Trenskow


As others have pointed out, you should definitely use the weakSelf pattern in situations where you would otherwise have strong reference cycles (aka, retain cycles). But more generally, you should use weakSelf whenever you don't want the block to retain the object itself (even in cases where there is no retain cycle involved).

A wonderful example would be a network operation that is initiated by some view controller. Let's say the user initiates some upload. The question is whether you want the asynchronous upload process to retain the view controller even though it might have a reference to that view controller to update some progress bar or the like. You may well not want it to retain the view controller if the view controller is dismissed, even though you might want to let the upload continue.

This is just a random example, but bottom line, you might want to use weakSelf pattern whenever you want the background process to continue, but you don't want it retaining the other object. Just look at your functional needs and consider the strong reference cycle risks, and make the decision whether you need to employ the weakSelf pattern or not.

In the case of animateWithDuration, the animation stops when the view is dismissed and the strong reference is immediately resolved, so there is no strong reference cycle.

like image 23
Rob Avatar answered Jan 14 '23 23:01

Rob