5

Bu yüzden blok eylemlerini bir nsmutabledictionary içine kaydediyorum ve sonra bir yanıt bir websocket'e geri döndüğünde bunları hatırlıyorum. Bu, async isteğini bir blok sözdizimine dönüştürür.blokları?

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

Not: Burada soyunmuş kod sunucu isteği ile gönderilen bir CorrelationID ile cevap verir. Bu nedenle her yanıt, bu istek üzerinden her bir isteğe bağlanır.

Bu, beklediğimden daha iyi çalışıyor. Sahip olduğum soru şu ki bu şekilde blokları çalıştırmak güvenli mi? [MessageBlocks removeObjectForKey: correlationID] çağrılıyor; onu hafızadan kaldırmak için yeterli. Ön ARC'yi hatırlıyorum, block_release bir seçimdi.

cevap

8

Yığın tabanlı blokları bir kapta güvenle saklamak için kopyalamanız gerekir.

olmayan ARC kodu için
[self.messageBlocks setObject:[responseAction copy] forKey:correlationID]; 

, ayrıca bunu -autorelease gerekir.

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

Yardım eder.