Retain cycle created - need confirmation - ios

I have been going questions about retain cycle but most of them talk about defining a block explictly and holding a strong reference to it. None of them talks about just passing an inline block.
My understanding is that just passing block in a function as an argument, does not create a strong reference. But i just want to make sure I havent misunderstood.
So the question is:
Does passing a block in a member function create a strong reference?
[self someFunctionWithCompletionCallback:^{
[self completionFunctionality];
}];
In this case is self holding a strong reference on the block being passed?
That would decide if I need to pass in weakSelf or not.
Thanks

It depends on what that someFunctionWithCompletionCallback: does. If the method stores that block in a strong member variable, for example, it would cause a retain cycle. If the method just calls the block during its execution and does not store it, no permanent retain cycle is created.
Note that something like this:
- (void)someFunctionWithCompletionCallback:(void (^)())completionBlock {
dispatch_async(^{ completionBlock() });
}
Will retain self temporarily (until the async dispatch is completed), since dispatch_async will retain its block, which will retain the completion block, which will retain self.

Remember the definition of a cycle is A->B->A (where '->' means 'retains'). In your question, B is a block and A is an object defining the block literal. B->A is certainly true, because blocks retain objects referred to within them and B refers to A.
But does A->B? That's up to A. Just passing an object doesn't retain it (imagine if that were the case, infinite retains everywhere!). So how does A handle B? If A copies or retains B, then A->B, and you have a cycle. If it doesn't, you don't.

When you call [self completionFunctionality]; in block body it (block) retains self so it creates strong reference. When execution of block is finished, it becomes out of scope, as result it would be removed from stack and block breaks strong reference to self. It means that self couldn't be dealloced until block execution is finished. So it isn't retain cycle in common understanding.

This code doesn't create retain cycle. It would be retain cycle if the block was for example a strong or copy property

Related

Block/Closure Understanding

Need clarification on blocks and closure.
How blocks will retain the object? or why we need to use only weak inside block? What will happen if we don't follow this? Or please give some clarity on block.
The below one os for closure.
I have written some code like this. favouriteButton is a property of self.
favouriteButton.hidden = false
dispatch_async(dispatch_get_main_queue(), {
self._collectionView.reloadData()
})
It didn't gave any error. So I thought of doing UI in main thread. So I moved the code to disable hidden inside block like below.
dispatch_async(dispatch_get_main_queue(), {
favouriteButton.hidden = false
self._collectionView.reloadData()
})
It shows an error like
reference to property 'favouriteButton' in closure requires explicit
'self'
dispatch_async(dispatch_get_main_queue(), {
self.favouriteButton.hidden = false
self._collectionView.reloadData()
})
Could any one please explain how to use closure/block effectively.
Does the blocks and closures work in the same way?
In Swift (and Objective-C), a block is a closure. The term closure refers to an individually-executable block of code that captures the values of variables in the enclosing scope. In the case of Swift, the enclosing scope is usually a function, and only variables used within the block are captured.
The reason you need to preface class-level references (properties and function calls) with self. is to make explicit the capturing of self. Doing so allows you to specify how self (or any other object reference) is captured: strong (default) or weak.
There are two reasons to be careful with retaining objects (keeping strong references) within a block.
The most common concern is creating a retain cycle. This is where the block retains a strong reference to an object, which in turn has a strong reference to the block. Until one of the references is explicitly broken, neither the block, nor the object, will be released. (Releasing a block simply cleans up the captured variables. The executable code remains.)
A strong reference to an object within a block can keep the object alive longer than intended. For example, if a block keeps a reference to a view controller that is popped off a navigation stack, you likely don't want that block to act on the view controller when its executed. This can be avoided by capturing a weak reference to the view controller. This allows the view controller to be deallocated when it's popped, and the block becomes a no-op.

Do I need to use use Strongify and Weakify in blocks if the variable calling it is local [duplicate]

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 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 delegate methods I call self., am I causing a retain cycle? Does that mean I have to pass around this weak reference everywhere? Seems hokey.
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
First of all: self does NOT cause a retain cycle. This is an urban legend. The incorrectness is obvious: A single reference can never cause a cycle. The usage of self inside a block causes a retain cycle, if the block is directly or indirectly referred by self, too, for example via a property.
To your Q:
If you "call" a method inside the block, the message probably has the receiver self, so you have a usage of self inside the block. For this reason it is captured and retained.
If you really have no usage of self inside the block by neither using self nor using a property of self you do not have a usage of self and it is not captured, therefore not retained. But in this case you can have a dangling pointer or a nil'd reference.
You don't need to worry about references while the block is executing - eventually it finishes doing whatever it does, and all these references go away.
What you need to worry about are the references that are captured when the block is created. These references stay until the block goes away. So if your block has a reference to "self", that reference is there just because the block exists. And if you store that block in a property of self, you have a cycle.
So if you store a block as a property in self, then the block shouldn't capture self. That's easily done by letting it access and capture a weak copy of self. Remember that when the block is executing, the weak copy of self may be nil. Which means the self object has already left our world, and your block might not need to do anything.
Short answer: no, in this situation self is not retained.
Long answer
First of all, retaining self and a reference cycle are not the same thing. Reference cycle is a cycle of strong references between a number of objects: A->B->C->A is a retain cycle.
The general idea is, you want to always guarantee that if you are referencing self in a block, you don't reference this block strongly, and don't reference it through a chain of strong references. In reality, retain cycles can be used purposefully if you are making sure you're breaking the retain cycle under certain conditions. Not that I personally recommend this.
Take a look at documentation on Apple's website. It clearly states that values are captured in blocks, and capturing an object reference retains this object in block.
Basically what this means is that referencing an object in a block increments its retainCount by 1, and when this block gets deallocated, retainCount is decremented by 1.
However, when using a __weak pointer in a block, the retain count is untouched.
Here's an example:
- (void) doSomething {
NSLog(#"%#", self);
}
- (void) callBlock {
__weak typeof(self) weakSelf = self;
dispatch_block_t block = ^{
[weakSelf doSomething];
};
}
When you write [obj method:params] this actually translates into following call:
objc_msgSend(obj, #selector(method:), params). One of the features of Objective-C is that if you call a method on nil pointer, it returns nil. This is guaranteed by the fact that objc_msgSend(nil, #selector(anyselector), ...) always return nil. Note that SEL is just a const char[] under the covers, so it doesn't affect retain counts by any means.
Hence when the block will be executed, if your object was deallocated, the weak weakSelf variable will be nullified, and the block's body will translate into objc_msgSending to zero, which does nothing except of wasting few CPU cycles.
To sum it up, the Objective-C messaging system is implemented in such a way that calling a method does not retain this object or this method or this method's implementation, as it's a simple function call.

Do I need to use a weak self pointer if a method called from a Block uses self?

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 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 delegate methods I call self., am I causing a retain cycle? Does that mean I have to pass around this weak reference everywhere? Seems hokey.
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
First of all: self does NOT cause a retain cycle. This is an urban legend. The incorrectness is obvious: A single reference can never cause a cycle. The usage of self inside a block causes a retain cycle, if the block is directly or indirectly referred by self, too, for example via a property.
To your Q:
If you "call" a method inside the block, the message probably has the receiver self, so you have a usage of self inside the block. For this reason it is captured and retained.
If you really have no usage of self inside the block by neither using self nor using a property of self you do not have a usage of self and it is not captured, therefore not retained. But in this case you can have a dangling pointer or a nil'd reference.
You don't need to worry about references while the block is executing - eventually it finishes doing whatever it does, and all these references go away.
What you need to worry about are the references that are captured when the block is created. These references stay until the block goes away. So if your block has a reference to "self", that reference is there just because the block exists. And if you store that block in a property of self, you have a cycle.
So if you store a block as a property in self, then the block shouldn't capture self. That's easily done by letting it access and capture a weak copy of self. Remember that when the block is executing, the weak copy of self may be nil. Which means the self object has already left our world, and your block might not need to do anything.
Short answer: no, in this situation self is not retained.
Long answer
First of all, retaining self and a reference cycle are not the same thing. Reference cycle is a cycle of strong references between a number of objects: A->B->C->A is a retain cycle.
The general idea is, you want to always guarantee that if you are referencing self in a block, you don't reference this block strongly, and don't reference it through a chain of strong references. In reality, retain cycles can be used purposefully if you are making sure you're breaking the retain cycle under certain conditions. Not that I personally recommend this.
Take a look at documentation on Apple's website. It clearly states that values are captured in blocks, and capturing an object reference retains this object in block.
Basically what this means is that referencing an object in a block increments its retainCount by 1, and when this block gets deallocated, retainCount is decremented by 1.
However, when using a __weak pointer in a block, the retain count is untouched.
Here's an example:
- (void) doSomething {
NSLog(#"%#", self);
}
- (void) callBlock {
__weak typeof(self) weakSelf = self;
dispatch_block_t block = ^{
[weakSelf doSomething];
};
}
When you write [obj method:params] this actually translates into following call:
objc_msgSend(obj, #selector(method:), params). One of the features of Objective-C is that if you call a method on nil pointer, it returns nil. This is guaranteed by the fact that objc_msgSend(nil, #selector(anyselector), ...) always return nil. Note that SEL is just a const char[] under the covers, so it doesn't affect retain counts by any means.
Hence when the block will be executed, if your object was deallocated, the weak weakSelf variable will be nullified, and the block's body will translate into objc_msgSending to zero, which does nothing except of wasting few CPU cycles.
To sum it up, the Objective-C messaging system is implemented in such a way that calling a method does not retain this object or this method or this method's implementation, as it's a simple function call.

When is self deallocated while dismissing view controller

I have a question regarding memory deallocation and blocks/closures.
Following is the Swift method
self!.dismissViewControllerAnimated(false, completion: {
println(self);
})
Or the objective C method
[self dismissViewControllerAnimated:NO completion:^{
NSLog("%#",self);
}];
I would really appreciate if anyone could explain when in the above method self would be deallocated . Is it after the completion block is run or before that? I understand its taken care by ARC but I would like to know if self gets release message in the completion block or after that. Hence, if I do some minor clean up in the completion block (accessing self), is that safe/acceptable or not?
There are really two separate questions to understand the answer completely:
1. When Are Variables Referenced Inside of Closures Released?
You can think of a closures as just another type (in Swift they really are). Every closure creates a strong ownership over the variables referenced inside of it, including self. This ensures that you never reference a variable that has been deallocated. Just like in any other object, when the closure gets deallocated, it releases its ownership over all of its variables.
If the closure is the only thing with a strong reference to that a variable, the variable will be dealloced when the closure is dealloced.
So in short, variables stay in memory as long as the closure is still in memory.
2. When Are Closures Deallocated?
Now the second part of this that is important to understand, is when does a closure get dealloced. You could store a closure in a variable:
func myMethod() {
var myClosure = {
println(self)
}
myClosure()
}
In this case, the closure has a strong reference from its variable myClosure and the closure has a strong reference to self. As soon as myClosure goes out of scope, i.e. when myMethod exits, it will be dealloced. When that happens, self will be released.
You may also have a situation, like in your question, where you are passing a closure into another method. In this case, the method you are passing the closure into is capturing a strong reference to your closure. When that method exits, it will release your closure, the closure will be deallocated, and it will release all variables captured inside it.
The Exception
Sometimes it is necessary to define a closure that does not take ownership over a variable. You would do this to avoid circular references. You can read more in Apple's documentation on what a circular reference is and how to prevent them here. However, it is important to realize that unless you put in explicit effort (and code), closures will always capture strong references to variables referenced inside of it.
In Swift, while developing/debugging and trying to understand the timing of operations, you can add the following to your View Controllers (or any class), to track if or when the instance is a about to deallocated.
Although that won't help you detect 'strong reference cycles' described here:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
deinit {
println(__FUNCTION__, "\(self)")
}

How does this prevent block retain cycles?

I saw a solution to preventing block retain cycles here
But I am having trouble wrapping my head around why or even how it works.
In the example, a weak self reference is made and acted upon. I can see how this Breaks the cycle. However, within the block a strong reference is created. Wouldn't this recreate the retain cycle that we were trying to prevent in the first place?
Let's say for example that self is 0x123
Then weakself is also pointing to 0x123.
Then strongSelf would get set to 0x123 inside the block.
Wouldn't this make a retain cycle?(self has strong reference to block and strongSelf has a strong reference to self)
Let's say for example that self is 0x123 Then weakself is also pointing to 0x123. Then strongSelf would get set to 0x123 inside the block.
Wouldn't this make a retain cycle?
Actually, no; they do not all point directly at the same thing. The fact is that an ARC weak reference really does (behind the scenes) interpose an extra object into the mix. Let's call it a scratchpad object. It gives the illusion that we are pointing at the same object, but we are actually pointing through the scratchpad object, which does not retain the thing it points to. That's how ARC weak references work (also known as zeroing weak references); they involve special extra go-between scratchpad objects that can be retained without themselves retaining, thus breaking the chain.
In a retain cycle, A has a retain on B and B has a retain on A. Each will put a release on the other in its own dealloc, but that moment will never come.
In the block situation, A is self and B is the block. self put a retain on the block for whatever reason it did so (often rather obscure, having to do with copying, observers, etc.; it doesn't always happen, and in fact it happens much more rarely than most people seem to suppose). The block put a retain on self merely by virtue of the fact that it is a closure and self is referred to with in the block.
But by doing the weak-strong dance, we prevent this. What passes into the block is weakself,
which is actually a reference through the scratchpad object. The block can retain this, but it, in turn, does not retain self. Hence there is no retain cycle.
Within the block a strong reference is created. Wouldn't this recreate
the retain cycle that we were trying to prevent in the first place?
Yes, it does, but only temporarily. When strongSelf is initialized, it forms a strong reference to the current weakSelf value. (Or nil, if that object has been deallocated.) Once the block finishes running, this (local) strong reference will be released, breaking the cycle.
The problem is not a retain cycle per se (they happen all the time), but a long-lived retain cycle that keeps its objects alive for longer than expected.

Resources