如何将传入变量标记为__block?

时间:2013-02-04 05:59:23

标签: objective-c

所有。 我有一个方法:

-(void)connectToServer:(NSError**)error{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         //bla bla bla code;
         *error=[NSError bla bla bla];
    }
}

但是那个错误变量之后没有修改过。它没有块变量。如何将标记(NSError **)错误的此方法修改为__block变量。如果__block varibale仅用于局部变量?

现在我使用__block属性解决组织局部变量的问题:

-(void)connectToServer:(NSError**)error{
    __block NSError *localError=*error;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         //bla bla bla code;
         localError=[NSError bla bla bla];
    }
    *error=localError;
}

但是这个解决方案不像我,因为我需要重新声明__block NSError * localError = * error;

2 个答案:

答案 0 :(得分:3)

要从块中修改error,您不需要本地__block范围变量。直接分配*error = [NSError bla];已经可以了。

这是有效的,因为error被本地范围内的块捕获。虽然error无法修改,但可以取消引用到存储了一些NSError *x的地址,并且确实可以在块中更改此x

但是,您需要绝对确定NSError *x引用的任何变量error是否足够持久。

答案 1 :(得分:2)

亩。

你正在做的事情没有多大意义。 connectToServer:方法很可能在该块设置error变量之前返回,这意味着调用者不会有一个有效的对象要查看。

您需要让块调用另一个方法来处理导致的任何错误,或者同步运行块,以便在块完成之前connectToServer:不返回。

此外,在第二种情况下,您应该关注Cocoa convention for error handling并指示通过直接返回方法发生错误。

这应该重写为:

- (void)connectToServer
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //bla bla bla code including error generation
        dispatch_sync(/* Get appropriate queue; probably main */, ^{
            // Handle error somehow
        });
    });
}

或者:

- (BOOL)connectToServer: (NSError **)e
{
    __block BOOL success = NO;
    // Note: dispatch_sync()
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //bla bla bla code;
        success = /* Get success value */;
        *e = /* Get error */;
    });
    return success;
}