blocks in nsdictionary?

回眸只為那壹抹淺笑 提交于 2020-01-22 23:11:25

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/12310374/blocks-in-nsdictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!