5

Por lo tanto, estoy almacenando acciones de bloque en un nsmutabledictionary y luego las recuerdo cuando aparece una respuesta en un websocket. Esto convierte la solicitud asíncrona en una sintaxis de bloque. Aquí está el código reducido:bloques en nsdictionary?

- (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]; 
    } 
} 

Nota: El servidor responde con un correlationID que se envía con la solicitud. Entonces, cada respuesta está vinculada a cada solicitud a través de esa identificación.

Esto funciona a la perfección, mejor de lo que esperaba. La pregunta que tengo es que ¿es seguro ejecutar bloques de esta manera? Está llamando [messageBlocks removeObjectForKey: correlationID]; lo suficiente como para eliminarlo de la memoria. Recuerdo pre-ARC, block_release era una opción.

Respuesta

8

Debe copiar bloques basados ​​en pila para almacenarlos de forma segura en un contenedor.

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

Para el código de no-ARC, es necesario -autorelease también.

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

Espero que ayude.