2

iOSアプリから(Restkitを使用して)Webサービスを呼び出す次のメソッドがあります...

BOOL valid = NO;

RKObjectManager *objectManager = [RKObjectManager sharedManager];
NSString *servicePath = [WebServiceHelper pathForServiceOperation:[NSString stringWithFormat:@"/security/isSessionValid/%@", username]];
[objectManager getObjectsAtPath:servicePath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    BooleanServiceResponse *resp = [mappingResult firstObject];
    valid = resp.value;
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    NSLog(@"Error while validating session for user %@ : %@", username, error);
}];

return valid;

ただし、valid変数がブロック外で宣言されており、割り当てできないというエラーが表示されます。私は少しグーグルで調べて、代わりにこのように有効であると宣言するという推奨事項を見つけました...

__block BOOL valid = NO;

それはエラーを取り除きます。ただし、ブロック内で値を何に設定してもvalid、ブロックを終了するときに適切に設定されていないことがわかりました。メソッドが期待値を返すようにこの値を設定するにはどうすればよいですか?

4

2 に答える 2

5

ブロックの仕組みを理解していないようです。__block正しいですが、変数の可視性の問題ではありません。

ブロックは非同期で実行される関数であるため、そのブロックが実行されるたびvalidに に設定されresp.valueます。これは、return ステートメントよりも後で発生する可能性が非常に高くなります。

これまでのところ、設定が保証されていないオブジェクトを返すため、設計を変更する必要があります。

編集

- (void)didFinishValidation:(BOOL)valid {
   // Do whatever you like with the `valid` value
   if (valid) {
     //...
   } else {
     //...
   }
}

そしてあなたのブロックは

[objectManager getObjectsAtPath:servicePath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    BooleanServiceResponse *resp = [mappingResult firstObject];
    valid = resp.value;
    [self didFinishValidation:valid];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    NSLog(@"Error while validating session for user %@ : %@", username, error);
}];
于 2012-12-29T14:57:22.593 に答える
3

一般に、変数をブロック内から変更するには、変数を __block として定義する必要があります。ここでの問題は、ブロックが呼び出される前に "return" が呼び出されることです。この状況を処理する最善の方法は、このメソッドを - (BOOL)... として定義するのではなく、- (void)... として定義し、委譲またはブロック コールバックを介した結果の非同期。

于 2012-12-29T14:53:08.830 に答える