2013-07-30 59 views
0

我有類:Objective-C的併發處理

ClassX.m 

@property (assign) BOOL wasProcessed; 

-(void) methodA { //<- this can be called many times in short period of time 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self methodB]; 
    }); 
} 

- (void) methodB { 
    if (!self.wasProcessed) { 
     self.wasProcessed = YES; 

     //... some code 
    } 
} 

由於dispatch_async使用這樣幾個電話來的methodB可以同時在同一時間進行處理,下面的代碼必須是原子的:

if (!self.wasProcessed) { 
self.wasProcessed = YES; //e.g two calls can enter here before setting YES and it would be bad because I want to process it only one time 

這兩條線怎麼可以做成原子(檢查和設置變量)?我不想讓「self.wasProcessed = YES;」之後的原子碼所以如果移動到@synchronize(self)將不是很好的解決方案。如果我的想法有什麼問題,請指出,因爲我對這些主題的經驗不是很豐富,謝謝。

回答

0

嘗試@synchronized。雖然隨附的代碼正在線程上執行,但會阻止其他線程執行它。

- (void) methodB { 
    @synchronized(self) { 
     if (!self.wasProcessed) { 
      self.wasProcessed = YES; 

      //... some code 
     } 
    } 
} 
+0

我認爲會有一些解決方案的問題,但它似乎工作正常。謝謝。 – regularUser

0
-(void) methodA { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^(){ 
      [self methodB]; 
     }]; 
    }); 
} 

你的的methodB只會調用主線程,因此它將永遠不會同時進行。

+0

這會起作用,但不必要的麻煩,因爲它會將所有後臺線程與主線程相互關聯以調用此方法。順便說一句,對於幾乎所有情況,'dispatch_async(dispatch_get_main_queue(),...)'和[[NSOperationQueue mainQueue] addOperationWithBlock:...]'是等價的,因此這將是多餘的。 (是的,它們的語義存在非常細微的差異,但是這不會對此產生影響。) – ipmcc

+0

同意。我不知道dispatch_async和dispatch_get_main_queue,並認爲這是一些用戶的功能:)因此,如果dispatch_async(dispatch_get_main_queue(),...)和[[NSOperationQueue mainQueue] addOperationWithBlock:...]做同樣的事情,那麼'methodB'不需要同步。 –