2013-06-21 35 views
1

我如何遞增的NSNumber這是GCD塊內:增量的NSNumber內GCD塊

-(void) doSomethingIntensive:(NSNumber *) value 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 

    dispatch_async(queue, ^{ 

     value = [NSNumber numberWithInt:[value intValue] + 1]; 

    }); 
} 
+0

C仍然通過價值。 – 2013-06-21 20:47:50

+0

而'NSNumber'仍然不是'int'。 – 2013-06-21 20:48:51

+0

什麼是C?由於它位於塊內,因此我無法更改值變量。我需要以某種方式將它標記爲__block變量,但在哪裏! –

回答

3

指針從塊繼承被認爲是「只讀」。爲了修改值,你需要在__block的前面加上前綴。在你的情況下,你不能在value前加__block,因爲它是一個參數。即使你可以,你的GCD塊是異步的,並且會在你的CGD塊被調用之前返回。

對於你想做什麼,你需要做的是這樣的:

- (void)doSomethingIntensive:(NSNumber *)value complete:(void (^)(NSNumber *result))complete 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 

    dispatch_async(queue, ^{ 
     if (complete) complete(@(value.integerValue + 1)); 
    }); 
} 

你會叫這樣的功能是這樣的:

[doSomethingIntensive:@(1) complete^(NSNumber *result) { 
    NSLog(@"%@", result); 
}); 

總的想法是,當你的「密集操作」完成後,它會調用您的回調。

+0

'NSInteger * result' - 爲什麼/如何? – 2013-06-21 20:51:40

+0

所以必須使用完成塊。沒有辦法改變傳入的值。 –

+0

我不想要一個完整的處理程序。如果我將值作爲NSNumber傳遞,我想更改相同的值。 –

1

指針是雙重複制的:一次當您將它傳遞給該函數時,另一次將它傳遞給該塊。去解決這一點,你必須通過一個指針的指針,讓你能夠修改原來的指針值:

-(void) doSomethingIntensive:(NSNumber **) valueRef 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
    dispatch_async(queue, ^{ 
     if(valueRef) 
      *valueRef = [NSNumber numberWithInt:[*valueRef intValue] + 1]; 
    }); 
} 

小心競爭條件,如果你需要使用點在主隊列,那麼你需要保護它與互斥體的訪問。