2012-02-08 26 views
2

私は子供を強く参照している親がいます。子供は親に対して弱い参照を持っています。Objective-cでは、子プロセスが実行されているときに、親プロセスが子プロセスを中止するとどうなりますか?

親は、1つのスレッド上で子のメソッドを呼び出します。子メソッドが実行を終了する前に、親プロセスが子プロセスをデアロックできる可能性があります。このメソッドを返すまで親を解放するのを避けるために、これを同期させる明白な方法はありません。

どうなりますか?

編集:私はARCを使用していないよ、これはiOSの3.1.2

EDIT上で実行されます:何[NSValue valueWithNonretainedObject]を使用してはどうですか?これによれば

:オブジェクトがガベージコレクトされたとき https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcAPI.html

参照がゼロに設定されています。しかし、iOSはガベージコレクションを持っていないので、ぶら下がりポインタがありますか?

EDIT:この便利なポストを見つけたので、私は私があまりにもこのトピックについての学習を他の人とそれを共有するだろうと思った:

http://cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

答えて

-2

次の場合には(あなたををアークには適用されません。 ARCについて話しています)

おそらくクラッシュします。ただし、1つのメソッドの開始時には[self retain];にコールし、メソッドの実行が終了する前に(戻り前またはメソッドの終了前に)[self release];にコールすることができます。親は子にreleaseを呼び出しますが、これは(メソッドが実行されている場合は)保持されているため、retainCountは0より大きい必要があります(deallocが呼び出されたとき)。

このメソッドが親の弱い参照を使用する場合、解放されたときに、親は解放されたメモリにアクセスする子を防ぐためにchild.parent = nil;を呼び出す必要があります。

+0

これは本当に良いアドバイスのようです。私は経験が豊富ではないので、これについて他の人々の意見も聞きたいと思います。 – xcoder

+0

親がdeallocすると、子は何に戻りますか?親が値を返す子のメソッドを呼び出していて、子の返り値の前に親のdeallocがある場合、戻り値はどこに行きますか?それはクラッシュしますか?私はこれを解決するには、メソッド内で親を保持して解放することも考えていますか? – xcoder

+0

親からメソッドが(同期的に)呼び出された場合、親メソッドから子メソッドが呼び出されたため、戻り値は親に送られます(親メソッドから呼び出されたため、戻り値は待機しません)。このメソッドが非同期に呼び出された場合、メソッドが終了すると、子は '[parent callbackMethod];を呼び出すでしょうが、' parent'はnilに設定されています(解放時に 'parent.parent = nil;')何も起こりません。 @Moとして。可能であれば、取り消すか、子供たちが解錠する前にその実行を止めるまで待つほうがよい) –

1

よく設計されたコードを使用したい場合は、まずこの問題を回避する必要があります。たとえば、すべての子プロセスが完了したときにのみ親を解放するか、子メソッドが実行されていないときにのみ呼び出される完了ハンドラブロックに解放コードを挿入します。

しかし、ARCを使用している場合はbabbidiと同じです。つまり、メソッドの冒頭で、ローカル変数の親に強い参照(例:localParent)を保持します。これにより保持サイクルが作成されるため、オブジェクトは解放されません。 localParentはローカルなので、メソッドの最後に自動的に解放され、保持サイクルが解除され、両方のオブジェクトが解放されます。

あなたの方法は、効果的に自動解放の挙動をシミュレートするために、非同期ブロック内のローカル親を使用し、値を返した場合:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [localParent self]; // this does nothing 
}); 
+0

ご返信ありがとうございます。おそらく私のデザインは弱い参照をすべて避けるべきだと私は思う。しかし、現時点では、アプリケーションをクラッシュさせることはできませんでした。スレッドスケジューラがすべてのスレッドを効果的に正しい順序で停止させるように見えるからです。しかし、これはサードパーティのコードであるため、これを検証する必要があり、すべてのスレッドがdeallocが開始される前に実行を終了することが偶然になる可能性があります。 – xcoder

3

をあなたのようなものを使用している場合:

[NSThread detachNewThreadSelector: selctor target: theChildObject withObject: nil]; 

をあなたは何の問題を持っていません。スレッドは実行が完了するまで、ターゲットは保持されます(オブジェクトが提供されている場合はそのオブジェクトも保持されます)。そうでない場合は、適切な同期を調整する必要があります。親の子のための原子アクセサを持っています。

// in the parent interface 

@property (retain) id child; // Note no nonatomic 

// in the child thread 

id myChild = [parent child]; // myChild will be autoreleased in the current thread if the child property is atomic 
if (myChild != nil) 
{ 
    [myChild retain];    // not strictly necessary as long as the current autorelease pool is not drained 
    // do the stuff you need with myChild 
    [myChild release]; 
} 
+0

'dispatch_async()'についても同じことが言えます。ブロックが実行されている間、ディスパッチされたブロック内のオブジェクトはすべて保持されます。 – bbum

+0

したがって、非アトミックを使用すると、子はゼロになるか、スレッドの最後まで保持されますか?お返事をありがとうございます。 – xcoder

+0

私はこれを使用できないかもしれません - すべての子はNSMutableArrayに格納されます。配列のプロパティをアトミックに変更できますが、配列に格納されているので、どのように影響を受けますか? – xcoder

関連する問題