0

我的问题是我正在使用dispatch_async(dispatch_get_main_queue(), ^(void) { ... });异步调用方法,在此方法中,根据某些条件我将布尔值设置为YES. 当在这个方法中读取这个布尔值时,它总是被它的旧值读取,即NO.

奇怪的是,当我在检查 bool 的行上设置断点时,一切都按预期进行!

编辑:这是产生线程的代码

dispatch_async(dispatch_get_main_queue(), ^(void) {
    [self drawFaceBoxesForFeatures:features forVideoBox:claporientation:curDeviceOrientation image:img];
});

方法本身

- (void)drawFaceBoxesForFeatures:(NSArray *)features forVideoBox:(CGRect)clap orientation:    (UIDeviceOrientation)orientation image:(UIImage *)image;
{
    if (![self getSendingRequestStatus]) {
        NSLog(@"Sending req");
        // send async request

         dispatch_async(dispatch_get_main_queue(),^ {
             sendingRequest = YES;
         } );
      }
}
4

2 回答 2

3

看起来您正在修改在块内部的块之外创建的 ivar。为了做到这一点并使 ivar 保持正确的值,您将需要__block像这样使用关键字:

@interface MyCoolClass : NSObject {
    @private
    __block int sendingRequest_;
}

正如杰克劳伦斯在上面的推荐中所说,“[运行时] 在那个时间点拍摄所有相关对象/变量的快照”。标识符将__block告诉运行时它不应该将该 ivar 复制到堆中,并允许您将值分配给sendingRequest_块内部,即使该块只是在主线程上运行。

可以在Blocks Programming Guide中找到很多好的入门信息(包括上述信息) 。

于 2012-04-16T21:40:31.270 回答
1

当原语被传递到一个块中时,它们被复制。因此,如果您将原始局部变量或实例变量放入块中,然后在创建块的同一方法(在创建块之后)或其他方法中更改它,它不会对块中的变量产生任何影响。对于局部变量,只需确保在创建块之前进行任何必要的更改。对于实例变量,您可以尝试使用某些 C: 来访问实例变量,self->iVar或者将其声明为属性并通过属性访问器访问它:self.iVar

于 2012-04-16T21:23:27.013 回答