我的问题是我正在使用dispatch_async(dispatch_get_main_queue(), ^(void) { ... });
异步调用方法,在此方法中,根据某些条件,我将布尔值设置为YES
。当在此方法中读取此布尔值时,总是通过它的旧值NO
读取。
奇怪的是,当我在检查布尔的线上做了一个断点时,一切都很顺利,按照预期进行!
编辑: 这是产生线程的代码
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;
} );
}
}
答案 0 :(得分:3)
看起来您正在修改在块内部块之外创建的ivar。为了做到这一点并让ivar保持正确的值,您需要使用__block
关键字,如下所示:
@interface MyCoolClass : NSObject {
@private
__block int sendingRequest_;
}
正如杰克劳伦斯在上面的推荐中所说,“[运行时]会拍摄当时所有相关对象/变量的快照”。 __block
标识符将告诉运行时它不应该将该ivar复制到堆中,并允许您将值分配给块内的sendingRequest_
,即使该块只是在主块上运行线程。
可以在Blocks Programming Guide找到许多好的信息(包括上述内容)。
答案 1 :(得分:1)
当基元传递到块中时,它们被复制。因此,如果您将一个原始的本地或实例变量放在一个块中,然后在创建块的相同方法(在块创建之后)或另一个方法中更改它,它将不会对块中的变量产生任何影响。对于局部变量,只需确保在创建块之前进行任何必要的更改。对于实例变量,您可以尝试使用某些C:self->iVar
来访问实例变量,或者将其声明为属性并通过属性访问器访问它:self.iVar
。