Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep blocks inside a dictionary

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:

  1. Blocks are objc objects
  2. Typo: setObject should be setValue
  3. forKey is a string so it should be [connection description] or something like that

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);
    });
}
like image 321
vgr Avatar asked Jun 15 '11 21:06

vgr


People also ask

How do I Bulid a dictionary in the blocks language?

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.

What does the list of pairs to dictionary block do?

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.

How do you create an empty dictionary in Python?

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.

What does the size of dictionary block return in Python?

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.


2 Answers

If you are using ARC, use -copy:

 void (^handlerCopy)(NSURLResponse*, NSData*, NSError*) = [handler copy];
 [dict setObject:handlerCopy forKey:@"foo"];
like image 21
Johan Kool Avatar answered Oct 18 '22 11:10

Johan Kool


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:.

like image 166
bbum Avatar answered Oct 18 '22 10:10

bbum