Objective C块和变量

时间:2012-12-29 14:50:17

标签: objective-c ios objective-c-blocks

我有以下方法从我的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变量上收到错误,说它在块外声明并且不可分配。我用Google搜索了一下,发现了一个建议,我宣布这样有效......

__block BOOL valid = NO;

摆脱了错误。但是,我发现无论我将valid值设置在我的块中,退出块时都没有设置。如何设置此值以使我的方法返回预期值?

2 个答案:

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

答案 1 :(得分:3)

通常,需要将变量定义为__block,以便从块中变换它们。这里的问题是在调用块之前调用“return” - 处理这种情况的最好方法是不将此方法定义为 - (BOOL)...但是 - (void)...并返回通过委托或阻止回调得到异步。