6

そのため、ブロック アクションを nsmutabledictionary に保存し、応答が websocket に戻ってきたときにそれらを呼び出します。これにより、非同期リクエストがブロック構文に変換されます。簡略化されたコードは次のとおりです。

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

注: サーバーは、要求と共に送信されたcorrelationID で応答します。したがって、各応答はその ID を介して各要求にリンクされます。

これは完璧に機能し、予想以上に優れています。私が持っている質問は、この方法でブロックを実行しても安全ですか? [messageBlocks removeObjectForKey:correlationID] を呼び出しています。メモリから削除するのに十分です。ARC以前のことを覚えていますが、block_releaseはオプションでした。

4

1 に答える 1

9

スタックベースのブロックをコンテナに安全に保存するには、それらをコピーする必要があります。

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

非ARCコードの場合は、-autoreleaseそれも必要です。

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

お役に立てば幸いです。

于 2012-09-07T00:58:37.570 に答える