Blocks and Variables - objective-c

At the moment I explore blocks opportunities, I read more then ten times apples docs) but i cant understand blocks behaviour in blogs examples and in my code. I know about __block modifier. So please look at few my examples, and say why it work or not:
1)Not working. Need __block, because I want to modified object.And self retained(correct?) and in blogs I'm frightened by retain cycle of self. Does it is?
NSDictionary *result = nil;
dispatch_async(queue, ^{
result = [self sendRequest:apiRequest];
});
2)Not working. I dont understand about variable scope of dispatch_async(dispatch_get_main_queue(), ^{});. Does it see all local variables in main thread or it is separate block from main thread, but exicuted in main thread? Like dispatch_async(dispatch_get_main_queue()^{}); copies all local variables in dispatch_async(queue,^{}); and switches semaphore to main thread.
NSDictionary *result = nil;
dispatch_async(queue, ^{
NSDictionary *data = [self sendRequest:apiRequest];
dispatch_async(dispatch_get_main_queue(), ^{
result=[data retain];
});
});
3)And examples from blogs and stanford's course that particularly muddle me, because they work.
- (void)viewWillAppear:(BOOL)animated
{
dispatch_queue_t downloadQueue = dispatch_queue_create(“image downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [NSData dataWithContentsOfURL:networkURL];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
 self.scrollView.contentSize = image.size;
});
});
dispatch_release(downloadQueue);
}
I dont understand, because first they dont mention about __block for self in the articles and the lessons, second this code modified variables, but through properties and complier doesn't swear that variables arent assignable and properties change reference, not value. Final it works. Thanks in advance.

Old question, but I feel like new readers might benefit from a more precise answer than the current one:
1) result is a pointer to an object, not an object itself. Prepending __block is necessary because that pointer is assigned to within the block. Modifying objects pointed to by pointer variables outside of the block is not the problem, e.g.
NSMutableDictionary* result = [NSMutableDictionary new];
and then modifying the object within the block via [result setObject...] would be fine. And that's the reason why 3) works: Only variables of the object pointed to by self are being modified. The pointer self is never assigned to.
Regarding retainment under ARC of the objects referenced by the block, see e.g.:
ARC with blocks and retain cycles
ARC, Blocks and Retain Cycles
blocks and ARC - copy or crash with release build (caused by optimization level)

1) Yes you'd need to declare:
__block NSDictionary *results = nil;
If you're using ARC it should automatically take care of retaining and releasing the results object. If not using ARC, then do a retain as the first thing you do and a release as the last thing you do in the block.
2) A block should have visibility of all variables/objects available to it's parent's scope. So in a method you should be able to see all local variables to that method and the object which that method belongs to (as self).
3) Not too sure about this one. Variables do go away once you leave the function/method (which will be as so as most blocks have been called, rather than finished executing), where as anything that is part of self won't. Maybe that has something to do with it.

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.

Instance variables and threading with GCD

I recently added threading to an app so that network requests are not blocking the UI. On doing this, I discovered that I could no longer set my instance variable the same way as I had before implementing threading. My instance variable is a property declared as follows:
#property (nonatomic, strong) NSMutableArray *currentTopPlaces;
Here is how I incorrectly set my instance variable self.currentTopPlaces:
dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
__block NSArray *topPlaces = [FlickrFetcher topPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableRowCount = [topPlaces count];
[[self currentTopPlaces] setArray:topPlaces];
});
Using [self currentTopPlace] setArray:topPlaces] worked fine in the blocking version, before I started using GCD.
Now, I must set it like so for things to work correctly:
dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
__block NSArray *topPlaces = [FlickrFetcher topPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableRowCount = [topPlaces count];
self.currentTopPlaces = topPlaces;
});
Can someone explain to me the difference between using:
[[self currentTopPlaces] setArray:topPlaces];
and:
self.currentTopPlaces = topPlaces;
Specifically, why the "setArray" call did not work in a threaded block?
I thought dot notation in Objective-C is syntactic sugar and not mandatory. I would like to know the "non-sugared" way to achieve the same behavior.
[self currentTopPlaces] and self.currentTopPlaces are in fact identical, but
[self.currentTopPlaces setArray:topPlaces]; // (1)
self.currentTopPlaces = topPlaces; // (2)
are not. (1) replaces all elements of self.currentTopPlaces with those from topPlaces. (2) assigns a new value to self.currentTopPlaces (releasing the old value if it was not nil).
A difference occurs if self.currentTopPlaces is nil: (1) does nothing, because the setArray: method is sent to nil. (2) assigns a new value to self.currentTopPlaces.
Btw: The __block modifier is not necessary in your code, because the block will not change the value of topPlaces.
[[self currentTopPlaces] setArray:topPlaces];
self.currentTopPlaces = topPlaces;
These are two entirely different expressions. The first is as written, the second would be:
[self setCurrentTopPlaces:topPlaces];
If you want to do the first one with dot notation, it would be:
self.currentTopPlaces.array = topPlaces;

accessing properties from blocks, Objective C

Hi I am trying to use queues and blocks to Multithread but I am having troubles accessing properties from these blocks. When I use NSLog to print the value of self.photoArray I get null. Can someone explain what I did wrong? I have tried This
dispatch_queue_t downloadQueue = dispatch_queue_create("flickrDownload", NULL);
dispatch_async(downloadQueue, ^{
NSArray* photos = [FlickrPhotoSort sortTopPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
self.photoArray = photos; });
});
dispatch_release(downloadQueue);
and this which doesnt use main queue.
dispatch_queue_t downloadQueue = dispatch_queue_create("flickrDownload", NULL);
dispatch_async(downloadQueue, ^{
NSArray* photos = [FlickrPhotoSort sortTopPlaces];
self.photoArray = photos;
});
dispatch_release(downloadQueue);
Here is the setter of photoArray
-(void) setPhotoArray:(NSArray *)photoArray{
if(!_photoArray) _photoArray = [[NSArray alloc] initWithArray:photoArray];
else
_photoArray = photoArray;
}
I am following the online stanford courses and the teacher simply called the property like this and it seems to work
dispatch_queue_t downloadQueue = dispatch_queue_create("flickr downloader", NULL);
dispatch_async(downloadQueue, ^{
NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationItem.rightBarButtonItem = sender;
self.photos = photos;
});
});
dispatch_release(downloadQueue);
When I use NSLog to print the value of self.photoArray I get null.
The asynchronously running [FlickrPhotoSort sortTopPlaces] is probably still running when you hit the log statement and the property just hasn't been set, yet.
Since properties invoke a method call I have had no issue setting them within a block. __block only adds visibility to a variable outside the scope of the block - so that changes to a variable from within the block are seen outside the block's scope. It has no effect on properties only on using vars directly in the block (where they be ivars or not.) properties are not ivars they are explicit method calls to a class which sets an ivar outside the scope of the block.
You should be retaining the photo array in the setter though - the array will be released at the end of the block otherwise. I have tons of code setting properties from within blocks with no issues.
Use the keyword __block for iVars in blocks. This makes sure, that the property stays in memory. If you use ARC and pre 5.0 use __unsafe_unretained else __weak
__block NSArray *bPhotoArray = self.bPhotoArray;
dispatch_async(downloadQueue, ^{
NSArray* photos = [FlickrPhotoSort sortTopPlaces];
bPhotoArray = photos;
});

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.

Memory management with block and ARC, leak?

I need to know if I do it correctly. The application is running OK but I'm not sure I get the lifecycle correctly (leak ?).
Note: Instrument see no leak.
The code of a method aaa: of some class A:
- (void) aaa {
NSString *path = ...something...;
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
// using path
[self somethingElseWith:path];
}];
[self.aQueue addOperation:theOp];
}
So I create a block to put on aQueue (NSOperationQueue*). The goal is to offload from the main thread the long running somethingElseWith: method, so that the GUI continue to be responsive.
Inside the block I reference the local var "path" that will be out of scope at the end of the aaa: method.
If I read the doc correctly, the block will do a retain on 'path'. But is ARC inserting a release at the end of this block implicitly ? Would be logical and nice.
Or should I declare 'path' as __block and assign it to nil at the end of my block ? (manual...)
Not sure I understand how to use __weak in this context.
The path variable is fine. You may however need to avoid a retain cycle by using a weak reference to self. If aQueue is a strong reference there may be a retain cycle causing self never to be released.
Solution:
- (void) aaa {
NSString *path = ...something...;
__weak id self_ = self;
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
// using path
[self_ somethingElseWith:path];
}];
[self.aQueue addOperation:theOp];
}
Make sure the operation does not get called after the class should no longer exist.
The block will automatically handle memory management for any locals from the enclosing scope. You don't have to worry about retain/release pairs in this case. Note, though that path will be const within the block's scope. If you need pathto be mutable within the block, use the __block attribute.
The different ways a block handles variables is described in detail here: Blocks and Variables