10

我讨厌积木。它们旨在使代码更简洁,但我找不到更难看的东西。例如,使用 AFNetworking:

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

这样的事情会好得多:

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

那么,是否可以将方法的选择器用作块?如果没有,我怎样才能使块代码更好?

这让我很恼火,因为这些块似乎是 Objective-C 编程的未来,它们只是不可读。

4

3 回答 3

7

所以你认为块结构使代码更难阅读?我认为它们有时可以使事情更容易理解,尤其是在异步上下文中,例如在网络代码中。

为了更容易阅读,您可以将块分配给变量。(实际上块是objective-c 对象。)

例子:

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

您还可以在块内调用单个处理程序方法以使其保持小。

于 2012-07-05T20:13:59.647 回答
2

短块是好的,过长的不是,你划线的地方当然是个人喜好......

对块使用方法并不难(反之则更具挑战性)。如果您想使用一种方法,最简单的方法是:

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

您可以使用宏走得更远,甚至performSelector/NSInvocation有趣 - 是否值得取决于您。

您还可以在调用本身之前移动块定义,如下所示:

var = block;
[object method:var];

您选择哪种方法是风格问题。

于 2012-07-05T20:24:05.903 回答
1

您可以剥离块,使它们不是方法调用的内联参数。它仍然涉及一些块丑陋,但仍然提高了一些可读性:

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];
于 2012-07-05T20:13:08.493 回答