2012-07-05 20 views
9

Tôi ghét các khối. Chúng có nghĩa là để làm cho mã ngắn gọn hơn, nhưng tôi không thể tìm thấy bất cứ điều gì xấu xí hơn. Ví dụ, với AFNetworking:Có cách nào để truyền các phương thức như các khối không?

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

Something như thế này sẽ tốt hơn nhiều:

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

Vì vậy, là nó có thể sử dụng bộ chọn phương pháp như khối? Nếu không, làm thế nào tôi có thể làm cho mã khối tốt hơn?

Nó làm phiền tôi, vì các khối này có vẻ là tương lai của lập trình khách quan-c và chúng chỉ KHÔNG đọc được.

+3

Các khối lúc đầu có vẻ 'xấu' nhưng chúng mạnh mẽ và có những lý do cụ thể mà chúng 'có vẻ là tương lai'. Tôi sẽ khuyên bạn nên bài viết này để có một cái nhìn sâu sắc tốt: http://ios-blog.co.uk/articles/tutorials/programming-with-blocks-an-overview/ – Alladinian

+1

Các khối không làm cho mã ngắn gọn hơn, chúng làm cho mã mạnh hơn. – dreamlax

+0

Đó là một câu hỏi hợp lệ, tôi nghĩ vậy. Vì cả hai khối có thể nhận các tham số (0..n) và trả về một tham số hoặc khoảng trống, các phương thức có thể được sử dụng như các khối ... hoặc đặt nó theo một cách khác, sẽ tốt hơn nếu xác định các khối ở cấp lớp. Tôi không nghĩ rằng bạn có thể ... –

Trả lời

6

Vì vậy, bạn nghĩ rằng cấu trúc khối làm cho mã khó đọc hơn? Tôi nghĩ rằng đôi khi chúng có thể giúp mọi thứ dễ hiểu hơn, đặc biệt là trong các bối cảnh không đồng bộ như trong mã mạng.

Để giúp bạn đọc dễ dàng hơn, bạn có thể chỉ định các khối cho các biến. (Trên thực tế khối là đối tượng mục tiêu-c.)

Ví dụ:

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

Bạn cũng có thể gọi một phương thức xử lý đơn bên trong khối để giữ cho nó nhỏ.

+0

Nó sửa chữa rất nhiều vấn đề "phong cách", tôi nghĩ rằng đó là cách tốt nhất để đi. Cảm ơn ! –

1

Bạn có thể bóc các khối để chúng không phải là tham số nội dòng cho các cuộc gọi phương thức. Nó vẫn liên quan đến một chút xấu xí khối, nhưng vẫn cải thiện khả năng đọc một số:

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

khối ngắn là tốt, những người quá dài không, nơi bạn vẽ đường tất nhiên là một sở thích cá nhân ...

Sử dụng một phương pháp cho một khối không phải là khó khăn (theo cách khác xung quanh là nhiều hơn một thử thách). Phương pháp đơn giản nhất nếu bạn muốn sử dụng một phương pháp:

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

Bạn có thể đi xa hơn với các macro, hoặc thậm chí performSelector/NSInvocation vui vẻ - cho dù đó là giá trị của nó là tùy thuộc vào bạn.

Bạn cũng có thể di chuyển các định nghĩa khối trước khi cuộc gọi chính nó, dọc theo dòng:

var = block; 
[object method:var]; 

nào tiếp cận bạn chọn là một vấn đề của phong cách.

Các vấn đề liên quan