I have my own method that takes a block as an argument. I want to keep track of that block inside an NSDictionary. What is the best way to add the block to the dictionary?
I tried this code but after executing the line below (setObject...) the dictionary is still empty. I presume that is because the block is not of type NSObject. But what is the right way to do this?
- (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler {
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[pendingRequests setObject:handler forKey:connection];
}
EDIT:
Never mind. I don't know what I was thinking. 3 points:
Anyway I fixed my problem now like this:
- (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler {
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[pendingRequests setValue:handler forKey:[connection description]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
void (^handler)(NSURLResponse*, NSData*, NSError*);
handler = [pendingRequests valueForKey:[connection description]];
handler(nil, nil, nil);
});
}
In the blocks language, you can bulid this dictionary as follows: Figure 1: A blocks representation of the JSON code snippet shown above. The create empty dictionary block creates a dictionary without any key-value pairs. Entries can be added to the empty dictionary using the set value for key block.
The list of pairs to dictionary block converts an associative list of the form ( (key1 value1) (key2 value2) ...) into a dictionary mapping the keys to their values.
The create empty dictionary block creates a dictionary without any key-value pairs. Entries can be added to the empty dictionary using the set value for key block. The create empty dictionary block can also be turned into a make a dictionary block by using the blue mutator button to add pair entries.
The size of dictionary block returns the number of key-value pairs present in the dictionary. The list of pairs to dictionary block converts an associative list of the form ( (key1 value1) (key2 value2) ...) into a dictionary mapping the keys to their values.
If you are using ARC, use -copy
:
void (^handlerCopy)(NSURLResponse*, NSData*, NSError*) = [handler copy];
[dict setObject:handlerCopy forKey:@"foo"];
That still isn't going to work or, at best, will only work coincidentally.
You need to copy the handler
before shoving it in the dictionary. Something like:
void (^handlerCopy)(NSURLResponse*, NSData*, NSError*) = Block_copy(handler);
[dict setObject:handlerCopy forKey:@"foo"];
Block_release(handlerCopy); // dict will -retain/-release, this balances the copy.
And, yes, it should be setObject:forKey:
and objectForKey:
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With