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