Why does the following code work?

Can sombody tell me why the following code works? I know that it does. Specifically, look at the 'dict' variable. It is used in the fast itteration for loop. But wait, it's also used within the completionHandler block of code, but it doesn't have a __block specifier. Why does this work?


__block NSMutableArray *dumArray = [NSMutableArray arrayWithCapacity:3];

for (NSDictionary *dict in self.stuffArray) {

NSURL *url = [NSURL URLWithString:urlString];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

request.timeoutInterval = kTimeoutInterval;

[NSURLConnection sendAsynchronousRequest:request

queue:[NSOperationQueue mainQueue]

completionHandler:^(NSURLResponse *response,

NSData *data, NSError *connectionError) {

if (data.length > 0 && connectionError == nil) {

NSDictionary *message = [NSJSONSerialization JSONObjectWithData:data

options:0

error:NULL];

NSDictionary *daDict = [message objectForKey:@"result"];

NSString *theInfo = daDict objectForKey:@“stuff”]];

NSMutableDictionary *replacementDict = [dict mutableCopy];

[replacementDict setObject:theInfo forKey:@“TheInfo”];

NSDictionary *theDict = [[NSDictionary alloc] initWithDictionary:replacementDict];

[dumArray addObject:theDict];

}

}];

}

Accepted Reply

It works because the completion handler block is not assigning a new value to dict. The local variable dict is immutable without the __block specifier; the object to which it points is not necessarily. If it were a NSMutableDictionary instead of an NSDictionary then you could add or remove keys, even inside the block. But "dict = ..." would be a no-no.

Replies

It works because the completion handler block is not assigning a new value to dict. The local variable dict is immutable without the __block specifier; the object to which it points is not necessarily. If it were a NSMutableDictionary instead of an NSDictionary then you could add or remove keys, even inside the block. But "dict = ..." would be a no-no.

The __block specifier doesn't make a local variable available to a block. Blocks can use any local variables - however the local variables are immutable within the block. When you add __block to a local variable you are telling the compiler to make that variable mutable within the block that's using them. From the docs:


You can specify that an imported variable be mutable—that is, read-write— by applying the

__block
storage type modifier.


You can read more about blocks and variables in: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1

Your answer is correct as well. I wish I could give credit too.