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 に答える