Objective-C block lifetime and retain cycle - ios

I got a question regarding objc blocks. If you want to use self in a block you should weakify it and strongify it again in the block so you don't get into a retain cycle. In my case I also want to write a property of the class where the block exists in. Now I'm a little bit confused if this makes sense and if I ever can access this property later or if I totally loose the reference to this property.
Here's my code example:
__weak typeof(self)weakSelf = self;
void (^handleRequestBlock)(NSURLSessionDataTask*, id) = ^(NSURLSessionDataTask *task, id responseObject)
{
__strong typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
strongSelf->_response = [strongSelf extractResponseData:responseObject forRequestType:requestType];
[strongSelf postSuccessNotification:strongSelf->_response];
}
};
First of all make this code completely sense or is there something to optimize?
Could someone maybe explain again what happens internally in objc. I read several articles now and I am more confused than before about retain cycles. As far as I know a block is an object and if it captures vars the vars are copied internally and declared as const by default as long as you don't use the __block declaration (what about properties that life in a global scope?). I still don't completely get what's the lifetime of a block and why pointers could dangling around, because the whole block object and its content should be deallocated when they finished. If someone has the time I would appreciate a nerdy and detailed answer or a link to a good reading resource! :)
Thanks in advance :)

I want to explain 3 ways to write the block.
First: use self
void (^handleRequestBlock)(NSURLSessionDataTask*, id) = ^(NSURLSessionDataTask *task, id responseObject)
{
self->_response = [strongSelf extractResponseData:responseObject forRequestType:requestType];
[weakSelf postSuccessNotification:self->_response];
};
the block handleRequestBlock retain self, if self has a property that owns the block, there will be a retain circle. The block will keep self retained until you release the block. So if you release the block after call the block (set the block to nil to release it), the cycle will not exist.
Note: Most implementation will not release the block after call it, because we may need it afterwards, so the retain circle will exist all the time.
Second: Use weak self
__weak typeof(self)weakSelf = self;
NSLog(#"%p", &weakSelf) ;
void (^handleRequestBlock)(NSURLSessionDataTask*, id) = ^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(#"%p", &weakSelf) ;
weakSelf->_response = [strongSelf extractResponseData:responseObject forRequestType:requestType];
[weakSelf postSuccessNotification:weakSelf->_response];
};
the block will not retain self and if the instance of self is deallocated, weakSelf is nil.
More about this example: I add two lines of log to show that : the address of variable weakSelf out of the block scope and inside the block scope are different. Because weakSelf is a stack local and __weak variable, so block capture it with a variable that has same value of weakSelf but not send retain message to the instance it indicates, weakSelf here is another variable with different address.
Third: retain self only when it is needed.
__weak typeof(self)weakSelf = self;
void (^handleRequestBlock)(NSURLSessionDataTask*, id) = ^(NSURLSessionDataTask *task, id responseObject)
{
__strong typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
strongSelf->_response = [strongSelf extractResponseData:responseObject forRequestType:requestType];
[strongSelf postSuccessNotification:strongSelf->_response];
}
};
There is a disadvantage on the second way: If self is not deallocated when the block is executing the first line of code, after executing this line of code , the instance of self is deallocated (because we didn't retain it, it may be sent release method on other thread and it will be deallocated), at the second line of code , weakSelf is nil, so something bad will happen, it depends on the logic of your code.
So the third way solved that, it only retain self when the block is executing and release self at the end of the block (release means decrease retain count by 1).
More Links :
Working with blocks
A look inside blocks
How do i avoid caturing self in blocks...

Related

Should I use weakSelf in nested blocks?

I'm trying to correctly avoid retain cycles with blocks in Objective C, and am not sure about having nested blocks.
If I write a simple block like this:
[self doSomethingWithBlock:^{
[self doSomethingElse];
}];
The compiler catches and warns me that this could cause retain cycles. I change it as follows to avoid the cycle:
__weak __typeof(self)weakSelf = self;
[self doSomethingWithBlock:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf doSomethingElse];
}];
When I write something like this:
[self doSomethingWithBlock:^(MyObject* object){
[object doSomethingElseWithBlock:^{
[self doYetAnotherThing];
}];
}];
The compiler is happy, but I'm not convinced that it's safe. Even though there is an intermediary object in between, it still looks conceptually the same as above, but now it's a cycle with 3 retains.
Should it be like this instead?
[self doSomethingWithBlock:^(MyObject* object){
__weak __typeof(self)weakSelf = self;
[object doSomethingElseWithBlock:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf doYetAnotherThing];
}];
}];
Or like this?
__weak __typeof(self)weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
[object doSomethingElseWithBlock:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf doYetAnotherThing];
}];
}];
In this situation, you are not worried about cyclic references. What you are worried about is a situation where the object self isn't actually needed anymore, but using self inside a nested block would keep it unnecessarily alive. For example, if you have a view controller that should go away when the view is removed by the screen, but you download an image that you would like to display in the controllers view. If the image arrives long after the view is already gone, you don't want the view controller alive anymore.
Best is
__weak typeof (self) weakSelf = self;
before calling the outermost method. Then within every block that ought to use self, you add
typeof (self) strongSelf = weakSelf;
and use strongSelf within that block. Depending on the situation, you might want to check that strongSelf isn't nil at that point, but sending messages to strongSelf when it is nil has no effect, so if all you do is sending messages and getting or setting properties, then a check for nil is not necessary.
What happens if you don't do this? The difference will be that self may be kept alive unnecessarily into the innermost block, if you use self everywhere (or just in the innermost block).
You should not capture something weakly just because you get a warning from the compiler; the compiler warning is just guessing; it doesn't know how the methods you call make the references. You should only do this if you understand the architecture of the references and determine that there is a cycle and determine that capturing a weak reference instead still preserves the intended behavior. You haven't shown us the code of -doSomethingWithBlock:. It would only create a retain cycle if inside that method it assigns the block to a property or instance variable of self. Does it do that or not? If not, then there is no retain cycle, and there is no point to the outer block capturing self weakly.
Assuming that the outer block capturing self weakly is right, the examples where the outer block captures self strongly are out of the question. The remaining questions would be whether the inner block should capture self (or whatever version of self, e.g. strongSelf, is appropriate) strongly. In other words, whether you would do something like this:
__weak __typeof(self) weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[object doSomethingElseWithBlock:^{
[strongSelf doYetAnotherThing];
}];
}
}];
or something like this:
__weak __typeof(self) weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[object doSomethingElseWithBlock:^{
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doYetAnotherThing];
}
}];
}
}];
Again, the main issue to determine is whether there is a retain cycle if the inner block captures self strongly. There would only be a retain cycle if [object doSomethingElseWithBlock:... somehow assigns the block to a property or instance variable of self. But how could it? The method is called on object, not self. The method does not get self in any way. Unless there is something complicated going on, the method is not going to assign to a property or instance variable of self, so it is unlikely to create a retain cycle. This means that the inner block capturing self weakly is not necessary to prevent a retain cycle.
But whether the inner block captures self weakly or strongly could affect the behavior. Namely, if the inner block captures self weakly, self could be deallocated by the time the block is run, in which case [strongSelf doYetAnotherThing]; will not be executed, whereas if the inner block captured self strongly, it would keep self alive and [strongSelf doYetAnotherThing]; would be executed. So it depends on what -doYetAnotherThing does. If it performs some UI operation on self which is a UI view or something, then whether you perform it on a view that is no longer displayed doesn't make a difference. But if it for example sends something to the network or something, then whether or not it is executed can make a big difference.
Xcode 8 beta 4 underlines the self keyword, and warns of a possible retain cycle for having used it inside the block.
Per Apple Developer Connection's Programming in Objective-C (Working with Blocks):
Avoid Strong Reference Cycles when Capturing self If you need to
capture self in a block, such as when defining a callback block, it’s
important to consider the memory management implications.
Blocks maintain strong references to any captured objects, including
self, which means that it’s easy to end up with a strong reference
cycle if, for example, an object maintains a copy property for a block
that captures self:
#interface XYZBlockKeeper : NSObject
#property (copy) void (^block)(void);
#end
#implementation XYZBlockKeeper
- (void)configureBlock {
self.block = ^{
[self doSomething]; // capturing a strong reference to self
// creates a strong reference cycle
};
}
...
#end
The compiler will warn you for a simple example like this, but a more
complex example might involve multiple strong references between
objects to create the cycle, making it more difficult to diagnose.
To avoid this problem, it’s best practice to capture a weak reference
to self, like this:
- (void)configureBlock {
XYZBlockKeeper * __weak weakSelf = self;
self.block = ^{
[weakSelf doSomething]; // capture the weak reference
// to avoid the reference cycle
}
}
By capturing the weak pointer to self, the block won’t maintain a
strong relationship back to the XYZBlockKeeper object. If that object
is deallocated before the block is called, the weakSelf pointer will
simply be set to nil.
This site reportedly provides a means for making the self keyword weak whenever it's used inside a block; it also provides instructions for returning a weak self or class object formerly strong, strong again:
https://coderwall.com/p/vaj4tg/making-all-self-references-in-blocks-weak-by-default
Look at the answer for this question.
I'd do this
__weak typeof (self) weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
[object doSomethingElseWithBlock:^{
[weakSelf doYetAnotherThing];
}];
}];

Two ways of block for preventing retain-cycle

I usually use block like this if there might be a retain-cycle:
- (void)someFunction {
__weak __typeof(self) weakSelf = self;
[self setHandler:^{
[weakSelf doSomething];
}];
}
But recently I saw another way like:
- (void)someFunctionWithParam:(id)param {
__weak __typeof(param) weakParam = param;
[self setHandler:^{
__typeof(weakParam) strongParam = weakParam;
[strongParam doSomething];
}];
}
What's the difference between them?
Edit1: Does it mean the param won't be release when self running the handler?
In the second example, there is no benefit to creating the strongSelf variable in that specific case, but I can show you an example where there is a benefit.
In the first example, the statement [weakSelf doSomething] loads the reference in weakSelf, retains it, sends the doSomething message, and then (after doSomething returns) releases the reference. The second example does essentially exactly the same steps “by hand”.
Here's a slightly different example:
- (void)someFunction {
__weak __typeof(self) weakSelf = self;
[self setHandler:^{
[weakSelf doSomething];
[weakSelf doAnotherThing];
}];
}
In my code, suppose there's only one strong reference to the self object at the time the block is called. The [weakSelf doSomething] statement creates a second, temporary strong reference to it. While doSomething is running, another thread releases the other strong reference. When doSomething returns, the statement releases its temporary strong reference. Now self has no more strong references, so it is deallocated and weakSelf is set to nil.
Then the [weakSelf doAnotherThing] statement runs. It wants to load and retain the contents of weakSelf, but because weakSelf is now nil, the statement just uses nil. It sends the doAnotherThing message to nil, which is allowed and doesn't crash. It just does nothing. It doesn't call the method.
This might not be behavior you want. Maybe you always want doAnotherThing to run on self if doSomething ran. That's when you need the pattern in your second example:
- (void)someFunctionWithParam:(id)param {
__weak __typeof(self) weakSelf = self;
[self setHandler:^{
__typeof(weakSelf) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doAnotherThing];
}];
}
Here, when the block is called, it immediately stores a strong reference to self in strongSelf (or it stores nil if weakSelf has already been set to nil). The strongSelf reference can't be released until after the last use of the strongSelf variable, so it's impossible for self to be deallocated after doSomething but before doAnotherThing.

Do I need to check for nil on my strongSelf = weakSelf assignment inside a block?

For example, I'm using SVInfiniteScrolling (https://github.com/alexanderedge/SVInfiniteScrolling).
I have some code that looks like this...
- (void)initializeInfiniteScrollingForTableView {
__weak MyViewController *weakSelf = self;
[self.tableView addInfiniteScrollingWithActionHandler:^{
MyViewController *strongSelf = weakSelf;
if (!strongSelf.endReached) {
[strongSelf fetchData];
}
else {
[strongSelf.tableView.infiniteScrollingView stopAnimating];
}
}];
}
What I'm wondering is... do I need to check strongSelf for nil before using like this...
...
[self.tableView addInfiniteScrollingWithActionHandler:^{
MyViewController *strongSelf = weakSelf;
if (strongSelf) { // <== ** Is this needed? **
if (!strongSelf.endReached) {
Here is why I ask. From point #3 on this link (http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance) it says "The nil test is because, in a multithreaded situation, our weak reference to self may have vanished out from under us before the previous step; it would then be nil, because it’s an ARC weak reference, and in that case there would be no point continuing."
Is this check needed? I thought the first time you used the reference to weakSelf within the block, it is retained for the duration of the expression?
For the code you posted, checking for nil is unnecessary.
This line of code:
if (!strongSelf.endReached) {
Will eval to false if strongSelf is nil. Further reading: Sending a message to nil?
And then this line of code will execute:
[strongSelf.tableView.infiniteScrollingView stopAnimating];
That line will just do nothing at all (not even an error) if strongSelf is nil.
However, some developers consider it a best practice to check for nil anyway, incase somebody later adds the code and it does care about nil. So you should consider doing:
MyViewController *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
... the rest of your code ...
I think in your line:
if (!strongSelf.endReached) {
this will evaluate to YES if self is nil, which is not probably not you intend.
It happens that your code does the correct thing (do nothing) because both clauses only use self to call methods and then nothing will happen. The end result is the same as if you had the nil-check but the execution path is wrong. This might have consequences in the future if someone adds code that doesn't use self.
Your source is referring to the fact that weakSelf may have been deallocated and nil'd before execution of the block could even begin; and therefore, before strongSelf acquired a strong reference and retained it. The strongSelf is to ensure that the object referenced by weakSelf is not nil'd during the block's execution.
There is no notion in ARC of "using" a variable making it necessary to retain it when dealing with __weak variables -- __weak is explicitly opting out of this.
With that said, the check isn't strictly speaking necessary in this case, since messages to nil are always no-ops. If you intended to insert strongSelf into an array, or if it being deallocated between messages would put your program into an invalid state, it would be another matter.
To conclude, whenever you need to guarentee that a __weak variable will not be nil'd for a period of time, use __strong, and check before using it that it is not nil.

strong reference in block

I've known about the best practice of block is like that
__weak SomeObjectClass *weakSelf = self;
SomeBlockType someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
};
I understand using weakSelf is used to prevent retain cycle and using strongSelf in case of weakSelf might nil.
But I just wonder using strongSelf can cause retain cycle again because block capture and retain strongSelf and strongSelf is also pointer of self.
can someone give me a explain ,thanks.
Ask yourself: How long does strongSelf exists?
strongSelf only exists while the block is executing. So basically, it holds a strong reference while someMethod is executing, and not any longer.
I assume you meant
[strongSelf someMethod];
and not
[self someMethod];
because the former holds a strong reference to strongSelf (which is equal to self) while the block is executing while latter will hold a strong reference to self while the block exists.
From documentation:
You can use lifetime qualifiers to avoid strong reference cycles. For
example, typically if you have a graph of objects arranged in a
parent-child hierarchy and parents need to refer to their children and
vice versa, then you make the parent-to-child relationship strong and
the child-to-parent relationship weak. Other situations may be more
subtle, particularly when they involve block objects.*
In manual reference counting mode, __block id x; has the effect of not
retaining x. In ARC mode, __block id x; defaults to retaining x (just
like all other values). To get the manual reference counting mode
behavior under ARC, you could use __unsafe_unretained __block id x;.
As the name __unsafe_unretained implies, however, having a
non-retained variable is dangerous (because it can dangle) and is
therefore discouraged. Two better options are to either use __weak (if
you don’t need to support iOS 4 or OS X v10.6), or set the __block
value to nil to break the retain cycle.
And som more documentation:
If you need to capture self in a block, such as when defining a
callback block, it’s important to consider the memory management
implications.
Blocks maintain strong references to any captured objects, including
self, which means that it’s easy to end up with a strong reference
cycle
As to your example - no retain cycle there, as CouchDeveloper said, because block will keep reference to self only while being executed. But there will be, no matter your __weak declaration, if we change code to this:
__weak SomeObjectClass *weakSelf = self;
self.someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
};
Now we have retain cycle - we have reference to block and inside block we have reference to self. To avoid this, you should use __weak approach:
__weak SomeObjectClass *weakSelf = self;
self.someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
} else {
[strongSelf someMethod];
}
};
Some more articles:
https://coderwall.com/p/vaj4tg
http://teohm.com/blog/2012/09/03/breaking-arc-retain-cycle-in-objective-c-blocks/
First, you must understand life cycle of strongSelf, it only exists in someBlock, after someBlock finished the object referenced by strongSelf will be released.
When the someBlock translated to MRR will like this:
^{
SomeObjectClass *strongSelf = [weakSelf retain];
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
[strongSelf release];
};

Block in block, with __weak self

I'm trying to figure out if I do this right:
If I have one block, I'll do this:
__weak MyClass *weakSelf = self;
[self performBlock:^{ //<< Should I use self, or weakSelf here?
[weakSelf doSomething];
} afterDelay:delay];
But what happens if there's a block in a block? Would this be correct?
__weak MyClass *weakSelf = self;
[self performBlock:^{
[weakSelf doSomething];
[self performBlock:^{
[weakSelf doSomething];
} afterDelay:1.0f];
} afterDelay:delay];
Also, in the function below, do I need to use [block copy]?
- (void)performBlock:(void (^)(void))block afterDelay:(float)delay
{
if (block)
{
if (delay > 0)
{
[self performSelector:#selector(executeBlockAfterDelay:) withObject:[block copy] afterDelay:delay];
}
else
{
[self executeBlockAfterDelay:[block copy]];
}
}
}
- (void)executeBlockAfterDelay:(void(^)(void))block
{
if (block)
block();
}
In this case (below) use just strong self, because the block is copied just for those few seconds. And usually if you want the self to perform block, you want to it to stay alive until that time, so strong reference is perfectly okay.
[self performBlock:^{
[self doSomething]; // strong is OK
} afterDelay:delay];
Block inside a block? In your case those two block are just delayed one-shot blocks, so the same as above, use strong. But there are differences between blocks. If you store the block for longer time, maybe for multiple invocations you should avoid retain-cycles.
Example:
self.callback = ^{
[self doSomething]; // should use weakSelf
};
This may cause retain-cycle. In fact it depends on how the block is used. We see that the block is stored (copied) in property for later use. However, you can prevent the retain-cycles by nullifying block that will not be used any more. In this case:
self.callback(); //invoke
self.callback = nil; //release
When using ARC, you don't have to copy blocks yourself. There were bugs in early versions after blocks were added, but now the compiler under ARC knows when to copy blocks. It is clever enough to copy it in this case:
[self performSelector:#selector(executeBlockAfterDelay:) withObject:block afterDelay:delay];
Rather than implementing -performBlock:afterDelay:, just use dipatch_after(). Among other things, that's not a message delivered to an object, so there's no question of what receiver to target it at.
Actually, there's no memory management issue here at all. One typically only needs to do a "weak self" approach when an object retains a block and the block (perhaps implicitly) retains that same object. However, the object is not retaining the block. It is being retained by the framework until the -performSelector:withObject:afterDelay: fires, but that's not a retain cycle.
If there were a retain cycle, then you should not reference self in the blocks. So, your nested case is wrong in invoking a message on self rather than weakSelf.
Finally, yes, you do need [block copy] whenever you are keeping a block after execution leaves the scope of its declaration or if you pass it to non-block-specific API that does. That is, you don't need to copy a block when you pass it to, say, dispatch_async() because that's a block-aware API that knows to make its own copy as necessary. But -performSelector:withObject:afterDelay: is not block-aware. It just treats its argument as a generic object and retains it. So, you do have to copy the block when passing it to that.
One the most important thing to understand about blocks is that they capture a piece of code (including values) in an abstract entity that can be manipulated as an atomic object (keep it somewhere, pass it, copy, etc...). Actually it is implemented in a way that guarantee that by default your block will remain valid and executable safely later.
Then capturing and retaining the required dependencies inside the block is necessary.
Unfortunately, in some cases (quite often actually) the block is retained by the instance that creates it and it retains itself that instance. This is called a retain loop and makes your object and your block impossible to dealloc unless you break one of the retaining relation yourself. This can happen if you reference your block with an instance variable for example and you don't nillify it manually.
This is probably the main issue with blocks especially because sometime, you don't know that your block retains your self instance (NSAssert within your block for example). Then:
If you execute your block immediately and release it (use your block
with dispatch release it after execution) there is no risk since you
are sure your object referenced by self still exist.
But if the execution is delayed it is important to retain your object within your block. But in that case your object should not retain your block to avoid a retain loop (A retains B and B retains A). If you define and optionally reference your block in the private scope of method it is perfect.
About copy. Yes it can be safer to use copy if your block in passed as a method argument to be sure you have a clean exclusive block in this scope with a +1 retainCount. But maybe ARC already do it for you. Not sure about that. For example it performWithSelector seems to do it for free, then copy is not dangerous. Just a useless. Sometime the compiler can optimise that by removing it but it has to be checked.
I usually do this:
__unsafe_unretained __block id blockSelf = self;
and then use it in my blocks no issues.
So in your case:
__unsafe_unretained __block MyClass *blockSelf = self;
[self performBlock:^{
[weakSelf doSomething];
[self performBlock:^{
[weakSelf doSomething];
} afterDelay:1.0f];
} afterDelay:delay];
Also to make your life a tad easier - make a utilities class and put this in the header
void RunAfterDelay(NSTimeInterval delayInSeconds, dispatch_block_t block);
and then this in the .m file
void RunAfterDelay(NSTimeInterval delayInSeconds, dispatch_block_t block)
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC), dispatch_get_main_queue(), block);
}
Import the utilities into your prefix and you can go:
__unsafe_unretained __block MyClass *blockSelf = self;
RunAfterDelay(1.0f,^{
[blockSelf doSomething];
RunAfterDelay(delay,^{
[blockSelf doSomething];
})
});
I find it a bit nicer to read than the verbose default ones.
Hope this helps :)

Resources