Disappearing reference to self in a block under ARC - objective-c-blocks

I'm having trouble figuring out why a __weak reference to self is disappearing in the following block. Following Jiva's advice found here
http://blog.random-ideas.net/?p=160 I make a __weak reference to self outside the completion block, then make a strong reference to that weak reference within the block to hold on to it for the duration of the block.
The problem I'm having is that the weak reference (weakSelf) comes up nil when the block executes, but if I just make the call to self directly in the block everything works.
- (void)fetchItemList:(NSArray *)itemList withHandler:(ItemFetchCompletion)completionHandler
{
NSString *fetchString = [self fetchRequestUsingItemList:itemList];
NSURL *fetchUrl = [NSURL URLWithString:fetchString];
ASIHTTPRequest *itemListRequest = [ASIHTTPRequest requestWithURL:fetchUrl];
__weak FetchManager *weakSelf = self;
__weak ASIHTTPRequest *itemListRequestWeakRef = itemListRequest;
[itemListRequest setCompletionBlock:^{
ASIHTTPRequest *itemListRequestStrongRef = itemListRequestWeakRef;
ZAssert(weakSelf, #"weakSelf reference is nil.");
FetchManager *strongSelf = weakSelf;
NSData *fetchedData = [itemListRequestStrongRef responseData];
NSArray *fetchedItems = [strongSelf itemsFromFetchedData:fetchedData];
completionHandler(fetchedItems);
}];
[itemListRequest startAsynchronous];
}

Here is essentially what your code is doing:
Making a weak variable, weakSelf.
Passing a block to a function that references that weak variable.
A this point, self is not retained by the block nor the weakSelf variable. Then, when the block runs, weakSelf is put into a __strong variable, thus retaining any value that was in weakSelf. Unfortunately, if the original value of weakSelf, namely self was already deallocated, weakSelf would be nil already.
The compiler can see what external variables your block accesses, and then adds any necessary retains if those variables are __strong. The compiler does not care that you assign a __weak variable to an internal variable that happens to be __strong. This retain will happen when the block runs, not when it is created.
By using self directly from the block, the compiler sees that you are referencing a variable that is not __weak, and therefore automatically retains that variable for the lifecycle of the block. In cases like this, I see no reason why you wouldn't directly reference self in the block, unless you are worried about a circular retain cycle.

Related

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.

block in block cause self be retained, __block not work

Add: the problem happen when I copy the block inside the function:
[block copy]
I am already using __block to avoid retain self.
__block typeof(self) bself = self;
However, when there is another block in this block, and it use bself, self will still be retained.
As show in code below, the first bself will not retain self as expected. However, the 2nd bself will retain self.
__block typeof(self) bself = self;
[layer start:param1
completeHanlder:^{
bself.xx = localxx;
dispatch_async(dispatch_get_main_queue(), ^(void) {
... ...
[bself something];
});
}
];
anyone know reason behind ?
You are doing wrong but concept it's right, here the error:
__block
This is used to let a strong reference inside your block. You could for example change value outside your block.
The right way is doing with __weak that will receive a weak reference from your instance and prevent strong loop reference like this:
__weak typeof(self) bself = self;
And because __block that you created retain and strong reference :)

Why do we have to set __block variable to nil?

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.

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);