2012-07-05 11 views
9

Io odio i blocchi. Hanno lo scopo di rendere il codice più conciso, ma non ho trovato nulla di più brutto. Ad esempio, con AFNetworking:C'è un modo per passare i metodi come blocchi?

AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
      requestsuccess:^(NSURLRequest *request, NSURLResponse *response, id JSON) { 
    // Some 
    // very 
    // long 
    // (and as ugly as blocks) 
    // processing 
} 
        failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON)) { 
    // Failure code 
}] 

Qualcosa del genere sarebbe stato molto meglio:

AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
      requestsuccess:@selector(requestSuccess:response:json:) 
        failure:@selector(requestSuccess:response:error:)] 

Quindi, è possibile utilizzare i selettori del metodo come blocchi? In caso contrario, come posso migliorare il codice di blocco?

Mi dà fastidio, poiché questi blocchi sembrano essere il futuro della programmazione degli obiettivi e sono semplicemente NON leggibili.

+3

I blocchi all'inizio possono sembrare "brutti" ma sono potenti e ci sono ragioni specifiche per cui "sembrano essere il futuro". Ti consiglierei questo articolo per avere una buona visione: http://ios-blog.co.uk/articles/tutorials/programming-with-blocks-an-overview/ – Alladinian

+1

I blocchi non rendono il codice più conciso, fanno codice più potente. – dreamlax

+0

È una domanda valida, penso. Dato che i blocchi possono sia ricevere parametri (0..n) che restituire un parametro o void, i metodi dovrebbero essere utilizzabili come blocchi ... o per dirla in altro modo, sarebbe bello definire i blocchi a livello di classe. Non penso che tu possa ... –

risposta

6

Così si pensa il costrutto blocco rende il codice più difficile da leggere? Penso che a volte possono rendere le cose più facili da capire, specialmente in contesti asincroni come nel codice di rete.

Per semplificare la lettura, è possibile assegnare blocchi alle variabili. (Infatti blocchi sono oggetti Objective-C.)

Esempio:

typedef void(^SuccessBlock)(NSURLRequest *request, NSURLResponse *response, id JSON); 

SuccessBlock successBlock = ^(NSURLRequest *request, NSURLResponse *response, id JSON) { 
    // code block 
}; 

AFJSONRequestOperation* operation; 
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
                  success:successBlock 
                  failure:nil]; 

è possibile contattare un unico metodo di gestore all'interno del blocco per mantenerlo piccolo.

+0

Risolve un sacco di problemi di "stile", penso che sia il modo migliore per andare. Grazie ! –

1

È possibile rimuovere i blocchi in modo che non siano parametri in linea per le chiamate di metodo. Si tratta ancora di un po 'di blocco bruttezza, ma migliora la leggibilità ancora un po':

void (^successBlock)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON); 

successBlock =^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
    // Some 
    // very 
    // long 
    // (and as ugly as blocks) 
    // processing 
}; 
//do same for failure block as "failureBlock" 
... 

AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
      requestsuccess:successBlock 
        failure:failureBlock]; 
1

blocchi brevi sono buone, non quelli eccessivamente lunghi, in cui si disegna la linea è ovviamente una preferenza personale ...

Utilizzando un metodo per un blocco non è difficile (il contrario è più di una sfida). L'approccio più semplice, se si desidera utilizzare un metodo:

- (void) requestSuccess:(NSURLRequest *)request 
       response:(NSURLResponse *)response 
        json:(id)JSON 
{ 
    // Some 
    // very 
    // long 
    // (and as ugly as blocks) 
    // processing 
} 

- (void) requestFailure:(NSURLRequest *)request 
       response:(NSURLResponse *)response 
        error:(NSError **)error 
        json:(id)JSON 
{ 
    // Failure code 
} 

... 

AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     requestsuccess:^(NSURLRequest *request, NSURLResponse *response, id JSON) 
     { 
      [self requestSuccess:request response:response json:JSON]; 
     } 
     failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON)) 
     { 
      [self requestFailure:request response:response error:error json:JSON]; 
     }] 

si potrebbe andare ulteriormente con le macro, o anche performSelector/NSInvocation divertente - se vale la pena spetta a voi.

È inoltre possibile spostare le definizioni di blocchi prima della chiamata stessa, lungo le linee di:

var = block; 
[object method:var]; 

cui ci si avvicina sceglie è una questione di stile.

Problemi correlati