3

私のメインプログラムは、以下を実行するスレッドを生成します。

// alloc autorelease pool somewhere before
NSArray *blah = [NSArray arrayWithObject: @"moo"];
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah
      waitUntilDone: NO];
// release autorelease pool somewhere after

セレクターboonk:の実行が終了する前に自動解放プールが解放される可能性があるため、これはバグのように思えます。これにより、クラッシュが発生します。

だから、私の自然な次の動きは次のようになります:

// alloc autorelease pool somewhere before
NSArray *blah = [[NSArray alloc] initWithObject: @"moo"];
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah
      waitUntilDone: NO];
// release autorelease pool somewhere after


- (void)boonk: (id)data
{
   // do something with data
   [data release];   // release the ref count the thread added
}

これは間違いなくバグがありませんが、....不自然に思えます。この状況を処理するためのObjective-Cの参照カウント規則またはプロトコル(クロススレッドNO-投稿待ち)はありますか、それともそれが行われる方法の上の2番目の解決策ですか?

4

2 に答える 2

9

実際には、セレクターが実行performSelectorOnMainThreadれるまで引数を保持するため、実行する必要はありません。

于 2010-01-11T11:08:39.040 に答える
3

ルールは単純です。オブジェクトをスレッドAからスレッドBに渡すには、ハードリテンションが存在する必要があります。現在、文書化されているように、-performSelectorOnMainThread:(およびバリアント)、同期または非同期の呼び出しに関係なく、メソッドの実行が終了するまでオブジェクトを保持します。

ただし、一般に、送信スレッドを保持し、受信スレッドで解放されるモチーフを維持することは賢明です。これは意図的に明示的であり、自動保持/解放を行わない他のモデルに対して、将来のリファクタリングをサポートする可能性があります。

また、重要であるため繰り返すために、自動解放プールを使用してスレッド間でオブジェクトを保持することはできません。

于 2010-01-11T18:46:36.453 に答える