2015-01-02 8 views
5

Questa domanda è simile a ios NSError types ma la soluzione descritta non funzionava e credo che non sia proprio quello di cui ho bisogno.L'invio di 'NSError * const __strong *' al parametro di tipo 'NSError * __ autoreleasing *' modifica le proprietà di conservazione/rilascio del puntatore

Ho un metodo che esegue una chiamata asincrona e quindi richiama un blocco di completamento. Quando provo a passare il NSError ** al blocco di completamento, ottengo questo errore:

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

Il codice è il seguente: l'errore

+(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

Hai qualche incomprensione fondamentale di cosa significa puntatore-puntatore contro puntatore. – Andy

+0

Andy: Lo ammetto, mi ci vuole un po 'per capire qualcosa che in seguito risulta essere abbastanza ovvio! –

risposta

5

I suoi argomenti di blocco completamento sono sciocchezze totale.

Si dispone di una variabile NSError * err sullo stack di chiamate.

Si tenta quindi di passare l'indirizzo di err a un blocco di completamento che verrà chiamato nella thread principale. Nel momento in cui viene chiamato il blocco di completamento, la funzione è tornata a lungo e l'errore & è spazzatura. Se il blocco di completamento ha tentato di memorizzare qualcosa, memorizzerebbe un NSError * dove molto tempo fa la variabile err era in pila, probabilmente sovrascrivendo alcuni dati preziosi di un metodo completamente non correlato.

Questo non funziona con i blocchi di callback.

5

passaggio per valore, non per riferimento, vale a dire il cambiamento bloccare la firma a void (^)(AKAgentProfile * agentProfile, NSError * error) e passare error anziché &error.

-1

avete errore definito come argomento a

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

e poi di nuovo nel blocco, vi consiglio di rinominare quello in blocco come:

+(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); 
     }); 

    }); 
} 
Problemi correlati