Why do we have to set __block variable to nil? - objective-c

From the Transitioning to ARC Release Notes
Use Lifetime Qualifiers to Avoid Strong Reference Cycles
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.
Okay, so what's different about __block variable?
Why set to nil here? Is __block variable retained twice? Who hold all the reference? The block? The heap? The stack? The thread? The what?
The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.
MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
[myController release];
}];
As described, instead, you can use a __block qualifier and set the myController variable to nil in the completion handler:
MyViewController * __block myController = [[MyViewController alloc] init…]; //Why use __block. my controller is not changed at all
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil; //Why set to nil here? Is __block variable retained twice? Who hold all the reference? The block? The heap? The stack? The thread? The what?
};
Also why myController is not set to nil by compiler. Why do we have to do so? It seems that the compiler sort of know when myController will no longer be used again namely when the block expire.

When you have code of this form:
object.block = ^{
// reference object from inside the block
[object someMethodOrProperty];
};
object will retain or copy the block you give to it. But the block itself will also retain object because it is strongly referenced from within the block. This is a retain cycle. Even after the block has finished executing, the reference cycle still exists and neither the object nor the block can be deallocated. Remember that a block can be called multiple times, so it cannot just forget all the variables it references after it has finished executing once.
To break this cycle, you can define object to be a __block variable, which allows you to change its value from inside the block, e.g. changing it to nil to break the cycle:
__block id object = ...;
object.block = ^{
// reference object from inside the block
[object someMethodOrProperty];
object = nil;
// At this point, the block no longer retains object, so the cycle is broken
};
When we assign object to nil at the end of the block, the block will no longer retain object and the retain cycle is broken. This allows both objects to be deallocated.
One concrete example of this is with with NSOperation's completionBlock property. If you use the completionBlock to access an operation's result, you need to break the retain cycle that is created:
__block NSOperation *op = [self operationForProcessingSomeData];
op.completionBlock = ^{
// since we strongly reference op here, a retain cycle is created
[self operationFinishedWithData:op.processedData];
// break the retain cycle!
op = nil;
}
As the documentation describes, there are a number of other techniques you can also use to break these retain cycles. For example, you will need to use a different technique in non-ARC code than you would in ARC code.

I prefer this solution
typeof(self) __weak weakSelf = self;
self.rotationBlock = ^{
typeof (weakSelf) __strong self = weakSelf;
[self yourCodeThatReferenceSelf];
};
What happens is that the block will capture self as a weak reference and there will be no retain cycle. self inside the block is then redefined as __strong self = weakSelf before your code runs. This prevents self from being released while your block runs.

Related

Objective-C: Should we use weak self within block or assign weak self to strong before using it?

As we know, using strong self within a block can lead to retain cycles and memory leak. Is the common practice to use weak self in a block, or is it better to assign the weak self to strong within the block and then use it as such so the weak self is not released during block execution? Does it matter since weak self will be zero-ed out anyway?
Due to the volatile nature of weak variables, you should use them with care. If you are using weak variables in a multithreading environment, it is considered good practice to assign the weak variable to a strong one and check for nil before using. This will ensure that the object will not be released in the middle of your method, causing unexpected results.
Consider the following case:
__weak id var;
//...
if(var != nil)
{
//var was released here on another thread and there are not more retaining references.
[anotherObj performActionWithAnObjThatMustNotBeNil:var]; //<- You may crash here.
}
The compiler can be configured to throw a warning on a consecutive access of a weak variable.
On the other hand, if your use is in the main thread, and all calls to the object are on the main thread, this problem is moot, since the object will either be released before the block call or after, thus it being safe to access the weak variable directly.
There are two possible questions here that are easy to get confused:
Is it possible for a __weak reference to become nil in the middle of a method?
id __strong strongObject = ...;
id __weak weakObject = strongObject;
dispatch_async(dispatch_get_main_queue(), ^{
[weakObject method1]; // if weakObject is non-nil here
[weakObject method2]; // can it become non-nil here?
});
Yes! Xcode will even warn you about it.
Is it possible for self to become nil in the middle of a method if the method is called on a __weak lvalue as below?
id __strong strongObject = ...;
id __weak weakObject = strongObject;
dispatch_async(dispatch_get_main_queue(), ^{
// is it possible for weakObject to be deallocated
// while methodUsingSelf is being called?
[weakObject methodUsingSelf];
});
- (void)methodUsingSelf {
NSLog(#"%#", self); // Could this be non-nil
NSLog(#"%#", self); // while this is nil?
}
No! Joe Groff, of the Swift team at Apple, said so:
self is guaranteed kept alive by ObjC ARC while a method on self is
executing.
Clang's official ARC documentation covers this case in the Semantics/Reading subsection:
Reading occurs when performing a lvalue-to-rvalue conversion on an
object lvalue.
For __weak objects, the current pointee is retained and then released
at the end of the current full-expression. This must execute
atomically with respect to assignments and to the final release of the
pointee.
Thus, calling a method on a __weak variable, is roughly equivalent to the following Manual Retain/Release (MRR) code:
id retainedObject = ...;
id assignedObject = strongObject;
dispatch_async(dispatch_get_main_queue(), ^{
{
[assignedObject retain];
[assignedObject methodUsingSelf];
[assignedObject release];
}
});
Of course, in MRR, [assignedObject retain]; might crash because the object assignedObject points to might have been deallocated, so assignedObject might point to garbage. ARC doesn't have this problem because it zeroes weak references.
I think that even if using the weak will work and be retained as long as needed, assigning it to strong before using will make it more readable and "worries free"...:
__weak id weakThing = thing;
thing.someBlock = ^{
if (weakThing) {
id strongThing = weakThing;
strongThing doThisWithThat...
}
};
Compiler won't complain and it is safe and maybe not less importantly - easy to understand for John Doe who will try to read this code tomorrow....
You can continue to use the weak self. The only time you'd need to use strong self is if you are trying to access a self->ivar directly, instead of going through a property.

Using __block and __weak

I've read over this thread: What does the "__block" keyword mean? which discusses what __block is used for but I'm confused about one of the answers. It says __block is used to avoid retain cycles, but the comments underneath it leave me unsure.
I'm using it something like this:
self.someProperty = x; //where x is some object (id)
__block __weak VP_User *this = self;
//begin a callback-style block
this.someProperty = nil;
Do I need to use both __block and __weak? Any glaring problems with this way this looks?
__block is a storage qualifier. It specifies that the variable should directly be captured by the block as opposed to copying it. This is useful in case you need to modify the original variable, as in the following example
__block NSString *aString = #"Hey!";
void(^aBlock)() = ^{ aString = #"Hello!" }; // without __block you couldn't modify aString
NSLog(#"%#", aString); // Hey!
aBlock();
NSLog(#"%#", aString); // Hello!
In ARC this causes the variable to be automatically retained, so that it can be safely referenced within the block implementation. In the previous example, then, aString is sent a retain message when captured in the block context.
Note that this isn't true in MRC (Manual Reference Counting), where the variable is referenced without being retained.
Marking it as __weak causes the variable not to be retained, so the block directly refers to it but without retaining it. This is potentially dangerous since in case the block lives longer than the variable, since it will be referring to garbage memory (and likely to crash).
Here's the relevant paragraph from the clang doc:
In the Objective-C and Objective-C++ languages, we allow the __weak specifier for __block variables of object type. [...] This qualifier causes these variables to be kept without retain messages being sent. This knowingly leads to dangling pointers if the Block (or a copy) outlives the lifetime of this object.
Finally the claim that __block can be used to avoid strong reference cycles (aka retain cycles) is plain wrong in an ARC context. Due to the fact that in ARC __block causes the variable to be strongly referenced, it's actually more likely to cause them.
For instance in MRC this code breaks a retain cycle
__block typeof(self) blockSelf = self; //this would retain self in ARC!
[self methodThatTakesABlock:^ {
[blockSelf doSomething];
}];
whereas to achieve the same result in ARC, you normally do
__weak typeof(self) weakSelf = self;
[self methodThatTakesABlock:^ {
[weakSelf doSomething];
}];
You should use __block if you want to change variable value in block.
e.g:
__block BOOL result = NO;
dispatch_sync(dispatch_get_main_queue(), ^{
...
result = YES;
...
});
You should use __weak if you want to avoid retain cycles.
e.g.:
__weak typeof(self) wself = self;
self.foobarCompletion = ^{
...
wself.foo = YES;
...
};
You can combine them if there is a need.

class method where self if used within a block

I've got a class method that uses dispatch_once to create a static object. Inside the dispatch_once block I use [self class] and was wondering if I need to use a weak reference to self to avoid a retain cycle?
+ (NSArray *)accountNames{
static NSArray *names = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
names = [[[self class] accounts] allKeys];
names = [names sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
});
return names;
}
If I use a weak reference to self I get a warning:
+ (NSArray *)accountNames{
static NSArray *names = nil;
static dispatch_once_t predicate;
__weak TUAccount *wself = self;
dispatch_once(&predicate, ^{
names = [[[wself class] accounts] allKeys];
names = [names sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
});
return names;
}
Incompatible pointer types initializing 'TUAccount *__weak' with an expression of type 'const Class'
Because I get a warning I don't think I need to use a weak reference to self in this case but I wanted to see what you guys thought.
There is no reason to worry about a retain cycle here, because it's meaningless to retain or release a class object -- retain and release simply have no effect.
Your attempt at making a weak reference is wrong, because you are taking a class object self and trying to cast it to an instance of TUAccount. The two are completely different things.
Also, you can simplify:
names = [[[self class] accounts] allKeys];
Since self is already a class, [self class] == self, so do this instead:
names = [[self accounts] allKeys];
I have checked one more time iOS SDK Docs and found next:
Objective-C Objects
In a manually reference-counted environment, local variables used within the block are retained when the block is copied. Use of instance variables within the block will cause the object itself to be retained. If you wish to override this behavior for a particular object variable, you can mark it with the __block storage type modifier.
If you are using ARC, object variables are retained and released automatically as the block is copied and later released.
Note: In a garbage-collected environment, if you apply both __weak and __block modifiers to a variable, then the block will not ensure that it is kept alive.
If you use a block within the implementation of a method, the rules for memory management of object instance variables are more subtle:
If you access an instance variable by reference, self is retained;
If you access an instance variable by value, the variable is retained.
The following examples illustrate the two different situations:
dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});
Conclusion: I assume that there is no problem with using self in block. It will be retained and after execution released.
Moreover, you are not storing block in memory and using it directly. So it is copied to the heap, executed and pushed from it. I don't see any retain cycles.
Hope I am right!

code blocks with Grand Central Dispatch

I'm writing an app using ARC, and I'm wondering if the following will cause a problem. Specifically, I'm creating an object 'A', then using GCD I add a code block to the main thread's queue and in the code block I perform some operations on the weak reference to the object. But by the time the code block is executed, my object has already been nullified. Since the code block only has a weak reference to the object, will this cause a problem? Or does the compiler somehow know to keep a reference to the object since my code block needs it when it runs?
Foo *A = [[Foo alloc] init];
__weak Foo *weakA = A;
dispatch_async(dispatch_get_main_queue(), ^{
//...do something here with weakA
});
A = nil;
Thanks!
Why are you using __weak here? If you want the block to "keep a reference to the object since [your] code block needs it when it runs", then you don't need to do anything:
Foo *a = [[Foo alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
[a something];
});
In the above snippet, the block retains a, so it will exist when the block executes.
As this question explains, the only time you need to use __weak with blocks is to break retain cycles that occur when the block itself is going to be retained. For example:
__weak Foo *someObject = [bar getAFoo];
[someObject doSomeTaskWithCompletionHandler:^{
[someObject doSomethingElse];
}];
Here, if someObject were not declared to be __weak, then you would have a retain cycle since someObject would presumably retain the block (since it would need to keep the block until it was done doing some task), and the block retains someObject. Using __weak here tells the block not to retain someObject, so the error doesn't occur. And you don't need to worry about someObject being nil when the block executes, because someObject owns the block. (If someObject were to be deallocated, then the block wouldn't be executed).
This is an interesting question with some subtleties.
You've explicitly told the compiler to disregard the reference from within the block by tagging it as __weak, so this code is not sufficient to keep the object alive until the block has been executed. It sounds like you're clear on that already, though.
Normally, a weak reference such as weakA would be nullified when the object it refers to is deallocated. However, weakA is a stack variable, so when it's referred to in a block, the block receives a const-ified version of it that memorializes its value at the time of the block's creation. Presumably, this const copy of weakA can't be nullified. See this section of the Apple docs for more on this.
If you change the declaration of weakA to
__block __weak Foo *weakA = A;
then weakA is promoted off the stack and is writable both from its original context and from the block. It still won't keep the referred-to object alive on its own, but at the point of the block's execution you can check to see if its value is nil.
More details on __block can be found here - skip down to the section "ARC Introduces New Lifetime Qualifiers".

How can code inside an Objective-C block reference the block object itself?

self is merely a captured variable inside a block and doesn't reference the block itself, so how does a block reference itself without having an explicit captured variable for that purpose?
__block void(^strawberryFields)();
strawberryFields = [^{ strawberryFields(); } copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
strawberryFields);
you use the __block because the block will make a copy of the value of strawberryFields when the block is created which will be before the assignment.
you also must copy the block prior to any other copy operation or else you'll end up with a block that references the on-stack original version.
note that the above code leaks the block. Somewhere, there needs to be a release of that block to balance the copy.
I found this pattern to work and stable for ARC (automatic reference counting), both in Debug and Release builds.
-(void) someMethod
{
// declare a __block variable to use inside the block itself for its recursive phase.
void __block (^myBlock_recurse)();
// define the block
void (^myBlock)() = ^{
// ... do stuff ...
myBlock_recurse(); // looks like calling another block, but not really.
};
// kickstart the block
myBlock_recurse = myBlock; // initialize the alias
myBlock(); // starts the block
}
Initially I tried just putting a __block modifier to myBlock and use that variable directly to recurse within the block's implementation. That works on the ARC Debug build but breaks with an EXC_BAD_ACCESS on the Release build. On the other hand removing the __block modifier raises a "variable not defined when captured by block" warning (and I was reluctant to run it and test).
I have never tried this before and not 100% sure it's useful, if valid, but for example:
typedef void (^BasicBlock)(void);
__block BasicBlock testBlock;
testBlock = ^{NSLog(#"Testing %p", &testBlock);};
testBlock();
You probably have declare the variable with __block to prevent self-retain cycle.
The block needs some way to nil out its own reference. Typically it is done by storing the block in a property of the class.
Sometimes you can prefer to not use a property. Here is how you do it without a property:
__weak id weakSelf = self;
__block id block = ^{
if(weakSelf) {
// .. do whatever
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), block);
}
else {
block = nil;
}
};
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), block);
The key thing to keep in mind is that all code paths must lead to a block = nil. We do that here by calling the block every 5 seconds until weakSelf turns nil.
Note that in ARC, it's a little different -- __block object pointer variables are by default retained in ARC, unlike in MRC. Thus, it will cause a retain cycle. It is necessary for the block to capture a weak reference to itself (using __weak) in order to not have a retain cycle.
However, we still need a strong reference to the block somewhere. If there are no strong references, the block (which is on the heap since it's copied) will be deallocated. Thus, we need two variables, one strong and one weak, and inside the block use the weak one to reference itself:
__block __weak void(^weakBlock)();
void(^myBlock)();
weakBlock = myBlock = [^{ weakBlock(); } copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
myBlock);