0

UIViewこの新しいクラスのインスタンス メソッドのいずれかでサブクラス化する場合は、次のようにします。

[self removeFromSuperview];

[foo someMessage];
_a = _a + 1;
self.b++;
for (int i = 0; i < 100000000; i++) {
    self.b++;
    //NSLog(@"b is %i", self.b);
}

何が起こるか?スーパー ビューがこのビューの所有権を主張している唯一のビューであると仮定すると、selfすぐに割り当てが解除されますか?

foo最初の行は、外部オブジェクトを参照するローカル変数メッセージを送信していますsomeMessage。2 行目はローカル変数です_b。3 行目はプロパティbです。そして、次の数行は、少し遅れているだけです。

Xcode 4.5 と iPhone 5 (iOS 6) で試してみると、コードは実際にクラッシュすることなく実行されます。コードは の中で行われました-touchesBegan。ビューは、大きな遅延ループが終了した後にのみ画面に表示されなくなります。これはおそらくメイン ループが現在呼び出しているdrawRectためでrootViewController.viewあり、ビューが表示されなくなったことを示しています (ビューは遅延ループの前にビュー階層から消えましたが、反映されていません)。画面はまだです)。

ループを 1000 または 10000 までしかカウントしないようにし、NSLogそのループの内側を使用すると、数値は実際にはクラッシュせずにうまく出力されます。更新:しばらくの間はオブジェクトにアクセスできる可能性があると言われていますが、30 秒または 1 分間でもコードは問題なく実行されているようです。

では、これはどのように機能するのでしょうか。Instruments を使用している場合、このFooViewオブジェクトが「割り当て」テーブルから離れたのは、大きな遅延ループの後であることがわかります。FooViewそのため、 の時点ではなく、後でオブジェクトの割り当てが解除されなかったように見えるのは奇妙ですremoveFromSuperView

私も[self.presentingViewController dismissViewControllerAnimated ...]を却下しself、次の行self.presentingViewControllerが再び使用され、 にself.presentingViewControllerなりましnilたが、ループを追加して 10000 の整数プロパティをインクリメントし、 を使用して出力するNSLogと、それもうまく出力されました。

4

1 に答える 1

1

スーパー ビューがこのビューの所有権を主張する唯一のビューであると仮定すると、self はすぐに割り当て解除されますか?

はい、おそらくですが、メモリが実際に再利用またはクリアされるわけではありません。割り当て解除後に他に何も起こらなかった場合でも、有効なオブジェクトのように見えるものを取得できることがよくあります。

試す:

[self removeFromSuperview];
[self performSelector:@selector(tryToCrash) withObject:nil afterDelay:0.1];

//...

- (void)tryToCrash
{
    [foo someMessage];
    _a = _a + 1;
    self.b++;
    for (int i = 0; i < 100000000; i++) {
        self.b++;
        //NSLog(@"i is %i", self.i);
    }
}

これにより、実行ループの次の周回後にそのコードが発生するようにスケジュールされ、クラッシュが発生する可能性があります。主なことは、死んでいることがわかっているオブジェクトを使用していることです。これは、C の UB のレベルには達していませんが、特定の結果が得られる保証はありません。

ビューは、大きな遅延ループが終了した後にのみ画面に表示されなくなります。おそらくメイン ループが drawRect を呼び出しているためです。

そうです、ビューはそれぞれが実行ループを通過するたびに再描画され、それが必要であるとマークされている場合にのみ再描画されます。サブビューの 1 つが削除されているため、スーパービューはそのようにマークされます。この時点までサブビューの実際のリリースを延期することも可能です。

于 2012-09-27T19:11:11.277 に答える