Ausgabe
Ich habe angefangen, eine einfache JSON-RPC-TCP-Bibliothek in Objective C zu schreiben. Ich habe eine Methode, die eine RPC-Methode aufruft:
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
requestId:(id)requestId
success:(void (^)(id responseObject))success
failure:(void (^)(NSError *error))failure
{
NSAssert(NSClassFromString(@"NSJSONSerialization"), @"NSJSONSerialization not found!");
NSDictionary *requestObject = @{@"jsonrpc": @"2.0",
@"method": method,
@"params": parameters,
@"id": requestId};
NSError *error = nil;
NSData *jsondData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:&error];
if (error){
return failure(error);
}
[self->callbacks setObject:@{@"success": success ? [success copy] : [NSNull null],
@"failure": failure ? [failure copy] : [NSNull null]}
forKey:requestId];
NSString *str = [[NSString alloc] initWithData:jsondData encoding:NSUTF8StringEncoding];
NSLog(@"Sending: %@", str);
[self.socket writeData:jsondData withTimeout:-1 tag:1];
}
Die Klasse stellt im Grunde eine TCP-Verbindung dar, beim Aufruf der obigen Methode werden die JSON-Daten mit einer ID über TCP an den Server gesendet, der entweder einen Erfolg oder einen Fehler zurückgibt:
- (void) socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
NSError *error = nil;
[self.socket readDataWithTimeout:-1 tag:2];
// … rpc response parsing code here, removed for simplicity …
// detect if error or success
NSDictionary *cbs = [self->callbacks objectForKey:JSONRPCObjectId];
void(^success)(id resultObject) = [cbs objectForKey:@"success"];
success ? success(JSONRPCObjectResult) : nil;
return;
}
Jetzt bin ich mir nicht sicher, wie ich die success
und -Blöcke verfolgen soll. failure
Derzeit speichere ich sie in einer NSMutableDict
, wobei ich die requestId als Schlüssel verwende. Ist es in Ordnung, dies zu tun, oder gibt es einen besseren Ansatz, den ich verwenden sollte?
Lösung
Blöcke in object-c sind Objekte und Sie können sie genauso behandeln wie andere Objekte, daher ist das Speichern in NSDictionarys, NSArrays usw. vollkommen in Ordnung. Der einzige Haken ist, dass Blöcke, wenn sie ursprünglich erstellt werden, im selben Speicherbereich wie lokale Variablen existieren und daher nicht mehr gültig sind, wenn die Methode, in der der Block definiert ist, zurückkehrt, genau wie alle anderen lokalen Variablen, sodass Sie sie zuerst kopieren müssen , kopieren Sie sie einfach und fügen Sie die Kopie in die Sammlung ein. Es gibt eine Blockkopierfunktion, aber Sie können ihnen einfach eine Kopiernachricht senden [myBlock copy];
Beantwortet von – Nathan Day
Antwort geprüft von – Timothy Miller (FixError Admin)