2012-07-05 12 views
9

Odio los bloques. Están destinados a hacer que el código sea más conciso, pero no pude encontrar nada más feo. Por ejemplo, con AFNetworking:¿Hay alguna manera de pasar métodos como bloques?

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 
}] 

Algo como esto hubiera sido mucho mejor:

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

lo tanto, es posible utilizar los selectores de métodos como bloques? Si no, ¿cómo puedo mejorar el código de bloque?

Me molesta, ya que estos bloques parecen ser el futuro de la programación objetivo-c y simplemente NO son legibles.

+3

Los bloques al principio pueden parecer 'feos' pero son poderosos y hay razones específicas por las que 'parecen ser el futuro'. Te recomendaría este artículo para tener una buena idea: http://ios-blog.co.uk/articles/tutorials/programming-with-blocks-an-overview/ – Alladinian

+1

Los bloques no hacen que el código sea más conciso, hacen codigo mas poderoso – dreamlax

+0

Es una pregunta válida, creo. Dado que los bloques pueden recibir parámetros (0..n) y devolver un parámetro o un vacío, los métodos deben poder usarse como bloques ... o para decirlo de otra manera, sería bueno definir bloques en el nivel de clase. No creo que puedas ... –

Respuesta

6

Así que creo que el constructo bloque hace que el código sea más difícil de leer? Creo que a veces pueden hacer que las cosas sean más fáciles de entender, especialmente en contextos asíncronos, como en el código de red.

Para facilitar la lectura, puede asignar bloques a las variables. (De hecho bloques son objetos Objective-C.)

Ejemplo:

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]; 

También puede llamar a un único método de control en el interior del bloque para que sea pequeña.

+0

Soluciona muchos problemas de "estilo", creo que es la mejor manera de hacerlo. Gracias ! –

1

Puede pelar los bloques para que no queden parámetros en línea para las llamadas a métodos. Todavía implica un poco de bloque de la fealdad, pero aún así mejora la legibilidad alguna:

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

bloques cortos son buenos, no los excesivamente largas, donde se traza la línea es, por supuesto, una preferencia personal ...

El uso de un método para un bloque que no es difícil (al revés es más de una reto). El enfoque más sencillo si se desea utilizar un método:

- (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]; 
     }] 

usted podría ir más allá con las macros, o incluso performSelector/NSInvocation divertido - si vale la pena que depende de usted.

También puede mover los bloques de las definiciones antes de la llamada en sí, a lo largo de las líneas de:

var = block; 
[object method:var]; 

Qué se acerque a elegir es una cuestión de estilo.

Cuestiones relacionadas