2013-07-14 13 views
12

Sto usando AFNetworking per ottenere dati da un server:Valore di ritorno per la funzione all'interno di un blocco

-(NSArray)some function { 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
      NSArray *jsonArray =[JSON valueForKey:@"posts"]; 
     } 
     failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 

Quindi quello che sto cercando di fare qui è di restituire il jsonArray alla funzione. Ovviamente il ritorno non funziona.

+9

Non è possibile farlo. Dato che hai a che fare con una chiamata asincrona, il tuo metodo 'some function' tornerà molto prima che ci sia un valore da restituire. – rmaddy

+2

Ti suggerisco di fare un passo indietro e pensare a cosa fa il tuo codice. Presto capirai che ciò che vuoi non ha senso. –

+1

è possibile passare blocchi alla funzione che verrà eseguita in caso di esito positivo o errore. – stosha

risposta

19

Non è possibile utilizzare il blocco di completamento per creare un valore di ritorno per il metodo. Lo AFJSONRequestOperation funziona in modo asincrono. someFunction sta per tornare mentre l'operazione è ancora funzionante. Il successo e l'insuccesso I blocchi sono il modo in cui ottieni i valori risultanti dove devono andare.

Un'opzione è quella di passare il chiamante come argomento al metodo wrapper in modo che il blocco di completamento possa consegnare l'array.

- (void)goFetch:(id)caller 
{ 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

     [caller takeThisArrayAndShoveIt:[JSON valueForKey:@"posts"]]; 
    } 
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 

Si può anche fare in modo che il chiamante crei e superi un blocco per essere eseguito in caso di successo. Quindi goFetch: non ha più bisogno di sapere quali proprietà esistono sul chiamante.

- (void)goFetch:(void(^)(NSArray *))completion 
{ 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     if(completion) completion([JSON valueForKey:@"posts"]); 
    } 
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 
+4

takeThisArrayAndShoveIt - lol sul nome del metodo –

3

Come altri hanno già detto, non è possibile farlo quando si ha a che fare con chiamate asincrone. Invece di restituire l'Array previsto, si poteva passare un blocco di completamento come parametro

typedef void (^Completion)(NSArray* array, NSError *error); 

-(void)someFunctionWithBlock:(Completion)block { 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
      NSArray *jsonArray =[JSON valueForKey:@"posts"]; 
      if (block) block(jsonArray, nil); 
     } 
     failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
      if (block) block(nil, error); 
     } 
} 

Allora dove si chiama quella someFunction. Questo codice farà anche la corretta gestione degli errori per te.

[yourClassInstance someFunctionWithBlock:^(NSArray* array, NSError *error) { 
    if (error) { 
     NSLog(%@"Oops error: %@",error.localizedDescription); 
    } else { 
     //do what you want with the returned array here. 
    } 
}]; 
0

ho affrontato questo tipo di problema e lo risolvo con questo metodo di seguito. Ho visto le risposte sopra usando i blocchi. Ma questa soluzione era più adatta a quel tempo. La logica del metodo è semplice. È necessario inviare l'oggetto e il suo metodo come parametro e, dopo la richiesta, verrà chiamato quel metodo. Spero che aiuti.

+(void)request:(NSString *)link parameters:(NSDictionary *)params forInstance:(id)instance returns:(SEL)returnValue 
{ 
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    [manager GET:link 
     parameters:params 
     success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     [instance performSelector:returnValue withObject: responseObject]; 
    } 
     failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    { 
     [instance performSelector:returnValue withObject:nil]; 
     //NSLog(@"Error: %@", error); 
    }]; 
} 
Problemi correlati