Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

blocks in nsdictionary?

So I'm storing block actions into a nsmutabledictionary and then recalling them when a response comes back on a websocket. This turns async request into a block syntax. Here's the stripped down code:

- (void)sendMessage:(NSString*)message responseAction:(void (^)(id))responseAction
{ 
    NSString *correlationID =  (NSString*)[[message JSONValue] objectForKey:@"correlationId"];

    [self.messageBlocks setObject:responseAction forKey:correlationID];

    NSLog(@"Sending message: %@", correlationID);
   [webSocket send:message];
}

- (void)webSocket:(SRWebSocket *)wsocket didReceiveMessage:(id)message;
{
    NSString *correlationID = (NSString*)[[message JSONValue] objectForKey:@"correlationId"];
    NSLog(@"Incoming message. CorrelationID: %@", correlationID);
    void (^action)(id) = nil;
    if (correlationID) {
        action = [messageBlocks objectForKey:correlationID];
        if (action) action([message JSONValue]);
        [messageBlocks removeObjectForKey:correlationID];
    }
}

Note: The server responds with a correlationID that is sent with the request. So each response is linked to each request through that id.

This works perfectly, better than I expected. The question I have is that is it safe to run blocks this way? Is calling [messageBlocks removeObjectForKey:correlationID]; enough to remove it from the memory. I remember pre-ARC, block_release was an option.

like image 474
SJonRails Avatar asked Sep 07 '12 00:09

SJonRails


People also ask

What is NSDictionary in Objective c?

The NSDictionary class declares the programmatic interface to objects that manage immutable associations of keys and values. For example, an interactive form could be represented as a dictionary, with the field names as keys, corresponding to user-entered values.

Does NSDictionary retain objects?

An NSDictionary will retain it's objects, and copy it's keys. Here are some effects this has had on code I've worked on. Sometimes you get the same object you put in, sometimes not. Immutable objects are optimized to return themselves as a copy .

How do you set a value in NSDictionary?

You have to convert NSDictionary to NSMutableDictionary . You have to user NSMutableDictionary in place of the NSDictionary . After that you can able to change value in NSMutableDictionary . Save this answer.

How do you append NSMutableDictionary?

Use NSMutableDictionary addEntriesFromDictionary to add the two dictionaries to a new mutable dictionary. You can then create an NSDictionary from the mutable one, but it's not usually necessary to have a dictionary non-mutable. Save this answer.


1 Answers

You need to copy stack-based blocks in order to safely store them in a container.

[self.messageBlocks setObject:[responseAction copy] forKey:correlationID];

For non-ARC code, you need to -autorelease it also.

[self.messageBlocks setObject:[[responseAction copy] autorelease] forKey:correlationID];

Hope that helps.

like image 161
Jeffery Thomas Avatar answered Oct 11 '22 18:10

Jeffery Thomas