0

私は次のようにNSThreadを使用しています

NSThread * thread = [[NSThread alloc] initWithTarget:object selector:@selector(bg) object:nil];
[thread start];

後で、スレッドを停止して、次のようにオブジェクトの割り当てを解除します。

[thread cancel];
[object release];

これは問題なく機能しているようです。ただし、リークツールを見ると、コード(空のNSArray)からどこにも来ていない不思議なリークがいくつか見られます。mallocの履歴を見ると、NSArrayが「willChangeValueForKey」メソッドに割り当てられていることがわかります。このメソッドは、最終的に[objectdealloc]から呼び出されます。デリゲートをnilに設定していることがあります。そのデリゲートが監視されています(したがって、willChangeValueForKey?)。[objectdealloc]は[NSThreadexit]から呼び出されます。

私の推測では、これは[スレッドキャンセル]がスレッドをすぐにスピンダウンしないためです(結局、別のスレッドにあります)。次に、メインスレッドでオブジェクトを解放します。これにより、retainCountは1のままになります。その後、NSThreadは、実際にスピンダウンしたときにオブジェクトを解放します。これがリークの原因のようです。私は自分の仮定を検証するためにこの簡単な変更を試みました:

[thread cancel];

[NSThread sleepForTimeInterval:1];
// This makes it wait until the thread releases [object]

[object release];

質問:NSThreadにオブジェクトの割り当てを解除させるのはなぜ安全ではないのですか?それはdeallocでオブザーバーコードが安全でないことと関係がありますか?

4

1 に答える 1

1

メインスレッドはすぐに実行できるはず[object release]です。スレッドをキャンセルするまで、またはスレッドを起動するまで待つ必要はありません。 initWithTarget:暗黙的に保持しobjectcancel暗黙的に解放します。

object切り離されたスレッドのためにメインスレッドを存続させるために、メインスレッドを保持する必要はありません。

于 2013-02-15T00:49:02.920 に答える