2015-01-02 5 views
5

Diese Frage ist ähnlich wie ios NSError types aber die dort beschriebene Lösung hat nicht funktioniert und ich glaube, es ist nicht genau was ich brauche.Senden 'NSError * const __strong *' an Parameter vom Typ 'NSError * __ Autoreleasing *' Änderungen beibehalten/freigeben Eigenschaften von Zeiger

Ich habe eine Methode, die dauert führt einen asynchronen Aufruf und ruft dann einen Abschlussblock. Wenn ich versuche, die NSError ** zum Abschluss Block zu passieren, bekomme ich diesen Fehler:

Sending 'NSError *const __strong *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer

Der Code ist wie folgt:

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 
{ 
    dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(requestQueue, ^{ 
     NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid]; 
     NSURL *url = [NSURL URLWithString:parameterizedUrl]; 
     NSData *data = [NSData dataWithContentsOfURL:url]; 

     NSError * error = nil; 

     AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock(agentProfile,&error); 
     }); 

    }); 
} 
+2

Sie haben ein grundlegendes Missverständnis darüber, was Pointer-to-Pointer vs. Pointer bedeutet. – Andy

+0

Andy: Ich gebe zu, es dauert eine Weile, bis ich etwas herausgefunden habe, das sich später als ziemlich offensichtlich herausstellt! –

Antwort

5

Ihre Fertigstellung Block Argumente sind totaler Unsinn.

Sie haben eine Variable NSError * err auf dem Aufruf-Stack.

Sie versuchen dann, die Adresse von err an einen Abschlussblock zu übergeben, der im Hauptthread aufgerufen wird. Zu dem Zeitpunkt, an dem der Completion-Block aufgerufen wird, ist Ihre Funktion lange zurück und & ist ein Unsinn. Wenn der Completion-Block versucht hat, etwas dort zu speichern, würde er einen NSError * speichern, wo sich vor einiger Zeit Ihre err-Variable auf dem Stack befand, höchstwahrscheinlich einige wertvolle Daten einer völlig unverwandten Methode überschreibend.

Dies funktioniert nicht mit Callback-Blöcken.

5

Pass Fehler von Wert, nicht Bezug genommen wird, dh Änderung Blockieren Sie die Signatur auf void (^)(AKAgentProfile * agentProfile, NSError * error) und übergeben Sie error anstelle von &error.

-1

Sie haben Fehler als Argument definiert in

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 

und dann wieder in Block, empfehle ich Ihnen den einen in Block wie umbenennen:

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 
{ 
    dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(requestQueue, ^{ 
     NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid]; 
     NSURL *url = [NSURL URLWithString:parameterizedUrl]; 
     NSData *data = [NSData dataWithContentsOfURL:url]; 

     NSError * err = nil; 

     AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock(agentProfile,&err); 
     }); 

    }); 
} 
Verwandte Themen