有没有办法将方法作为块传递?

时间:2012-07-05 19:48:39

标签: objective-c objective-c-blocks afnetworking

我讨厌街区。它们旨在使代码更简洁,但我找不到更丑陋的东西。例如,使用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编程的未来,它们只是不可读。

3 个答案:

答案 0 :(得分:6)

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

为了便于阅读,您可以将块分配给变量。 (确实,块是客观的对象。)

示例:

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

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

答案 1 :(得分: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];

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

答案 2 :(得分: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];