5

Vì vậy, tôi đang lưu trữ các hành động chặn vào một nsmutabledictionary và sau đó gọi lại chúng khi một phản hồi trở lại trên một websocket. Điều này biến yêu cầu không đồng bộ thành cú pháp khối. Dưới đây là mã bị tước bỏ:khối trong 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]; 
    } 
} 

Lưu ý: Máy chủ phản hồi với một correlationID được gửi cùng với yêu cầu. Vì vậy, mỗi phản ứng được liên kết với mỗi yêu cầu thông qua id đó.

Công trình này hoàn hảo, tốt hơn tôi mong đợi. Câu hỏi tôi có là an toàn để chạy khối theo cách này? Đang gọi [messageBlocks removeObjectForKey: correlationID]; đủ để loại bỏ nó khỏi bộ nhớ. Tôi nhớ trước ARC, block_release là một lựa chọn.

Trả lời

8

Bạn cần sao chép các khối dựa trên ngăn xếp để lưu trữ chúng an toàn trong vùng chứa.

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

Đối với mã không phải ARC, bạn cũng cần -autorelease.

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

Hy vọng điều đó sẽ hữu ích.