2011-08-01 17 views
0

私はキューに提出するブロックを持っており、特定の条件が真であればブロックを実行したいだけです。それはこのようにソートのになります。コードブロック内の参照による変数の使用方法は?

bool hi = YES; 
dispatch_async(queue, ^{ 
    if (hi == YES) 
     do stuff; 
}); 

これに伴う問題であり、そのブロックの後にブロックのNO外部へのハイテク変化の値は、キューにそれが実行される前に提出された場合には、ブロック内のhiの値はまだYESです。

私はドキュメントを見て、__blockディレクティブを見つけました。これは助けになるかもしれませんが、うまくいきませんでした。

__block bool hi = YES; 
dispatch_async(queue, ^{ 
    if (hi == YES) 
     do stuff; 
}); 

bool hi = YES; 
dispatch_async(queue, ^{ 
    __block boolean hi2 = hi; 
    if (hi2 == YES) 
     do stuff; 
}); 

をそして、それらのどちらも動作するようです:私が試してみました。

答えて

2

__block BOOL hiを実行したときに、まだ逆参照するために周りにする必要が何をすべきあなたは欲しい。非同期でディスパッチする場合は、残りのブロックがなくても、hiをNOに変更する前にif (hi == YES)が実行されている可能性があります。あなたが実際にやっているべきことは、開始するべきかどうかを一度チェックするのではなく、定期的にhiをチェックして作業を続けるかどうかを確認することです。

+0

これを実行すると、期待通りに動作しますので、__blockディレクティブは参照を保持します。 BOOL b = YES; \tボイド(^ブロック)()= [[^ { \t \t IF(B == YES){ \t \t \tのNSLog(@ "B == YES")。 \t \t} else { \t \t \t NSLog(@ "b == NO"); \t \t} \t} autorelease]; \t b = NO; \t block(); – Mattia

1

私はブロックの専門家ではありませんので、内部にプリミティブ変数の値を取り込めない方法があるかどうかはわかりません(しかし、そうではないと思います)。しかし、この問題を解決するには、ポインタまたはNSNumberを使用することになります。

ポインタ

/* this obviously needs to still be around to be dereferenced when the block executes */ 
BOOL hi = YES; 
BOOL* hiPtr = &hi; 

dispatch_async(queue, ^{ 
    if (*hiPtr == YES) 
     do stuff; 
}); 

のNSNumber

/*これは明らかにブロックが*/

__block NSNumber* hi = [NSNumber numberWithBool: YES]; 

dispatch_async(queue, ^{ 
    if ([hi boolValue] == YES) 
     do stuff; 
}); 
関連する問題