2012-04-16 80 views
0

我的問題是,我使用dispatch_async(dispatch_get_main_queue(), ^(void) { ... });異步調用方法,在這種方法取決於一些條件我設置一個布爾值YES。當用這種方法讀取這個布爾值時,它的總是用讀取它的舊值,即NO從GCD線程讀舊值

奇怪的是,當我在布爾檢查的行上做了一個斷點時,一切都很順利!

編輯: 這裏就是線程派生

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

您使用的是LLDB還是GDB? – larsacus 2012-04-16 21:17:22

+0

是否在塊內創建了布爾值? – 2012-04-16 21:19:58

+1

當運行時遇到調度調用時,它會在該時間點拍攝所有相關對象/變量的快照。因此,即使稍後執行調度調用,它也會以調用時的狀態訪問變量。 – 2012-04-16 21:20:23

回答

3

看起來您正在修改在塊內部的塊外創建的ivar。爲了做到這一點,有伊娃保持正確的值,你將需要使用__block關鍵字,像這樣:

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

正如傑克·勞倫斯在上面的表彰說,「[運行]需要當時所有相關對象/變量的快照「。 __block標識符會告訴運行時,它不應該將該ivar複製到堆中,並允許您在塊內部爲sendingRequest_分配值,即使該塊只是在主線程上運行。

Blocks Programming Guide中可以找到許多有用的信息(包括上述信息)。

+0

謝謝你的提示和參考鏈接:) – 2012-04-16 22:07:01

1

當基元被傳遞到它們被複制的塊的方法本身。因此,如果將一個原始的本地或實例變量放在一個塊中,然後在創建該塊的同一方法(在創建塊之後)或其他方法中更改它,則它不會對該塊中的變量產生任何影響。對於局部變量,只要確保在創建塊之前進行必要的更改。在實例變量的情況下,您可以嘗試使用某些C:self->iVar訪問實例變量,或將其聲明爲屬性並通過屬性訪問器:self.iVar訪問它。

+0

嘗試使BOOL成爲一個屬性,並使用self.iVar讀寫它,但問題仍然存在。 – 2012-04-16 21:30:32

+0

直接訪問iVars是...在ObjC最好的粗略。 – CodaFi 2012-04-16 21:37:33

+1

@CodaFi實際上,直接訪問塊中的iVar應該沒問題。通過在塊中引用'self',該塊將自動保留'self',因此訪問它的任何iVars都像直接從類中引用它們一樣安全。 – 2012-04-16 21:40:44