0

私は奇妙なエラーだと思うものを持っていますが、もちろん私はiPhone開発に比較的慣れていないので、結局のところそれほど奇妙ではない可能性があります.

追跡しているオブジェクトの配列(NSMutableArray)があります(ユーザーがボタンに触れるたびに配列に追加されます)私がやろうとしているのは、配列が特定の値に達したときです新しいオブジェクトを追加します配列の先頭に移動し、配列内の最後のオブジェクトを削除します。コードをステップ実行すると、すべてが機能し、オブジェクトは削除されますが、アプリはクラッシュします...アプリがクラッシュしたときにデバッガーはコードのどの行にもありません。アプリにはまだループやタイマーがないので、できます。実行中のものは他に考えられません。

クラッシュの直前に実行されるコードは次のとおりです

if([objectArray count] > 10)
{
    MyObject *objectToRemove = [[MyObject alloc] init];
    objectToRemove = [objectArray objectAtIndex:10];
    [objectArray removeObjectAtIndex:10];
    [objectToRemove removeFromSuperview];
}

このコードの主なポイントは、ユーザーがボタンに触れるたびにオブジェクトが画面に追加されて表示され、オブジェクトの数が 10 に達してユーザーがもう一度ボタンに触れると、追加された最初のオブジェクトが削除され、新しいオブジェクトが表示されます。removeObjectAtIndex 行をコメントアウトすると、すべてが意図したとおりに機能しますが、配列は拡大し続けます。

UIview が削除された後、オブジェクトを削除しようとしましたが、アプリは同じように動作します。別のインデックス (IE 3) で配列からオブジェクトを削除しようとすると、アプリはクラッシュしませんが、期待した結果が得られません。しかし、私が言ったように、コードは正常に実行され、行の実行前後に配列の数をチェックすると、値はそれぞれ11と10です。

あなたが提供できる助けをいただければ幸いです。

BWC

4

2 に答える 2

6

これはあなたが思っていることをしないと思います。行ごとに行く:

MyObject *objectToRemove = [[MyObject alloc] init];

タイプ「MyObject.

objectToRemove = [objectArray objectAtIndex:10];

ローカルの MyObject ポインターを、objectArray のインデックス 10 にあるもので上書きします。最初に割り当てた objectToRemove がリークされました。

 [objectArray removeObjectAtIndex:10];

これで、インデックス 10 のオブジェクトが削除されました。配列からオブジェクトを削除すると、解放され、参照カウントが減少します。これにより、割り当てが解除される場合があります (または解除されない場合があります)。

 [objectToRemove removeFromSuperview];

ここで、以前 objectArray にあったオブジェクトにメッセージを送信しています。前のコード行によってオブジェクトの割り当てが解除された場合、クラッシュが予想されます。

宣言のリークを脇に置くと、これを行うことができる場合があります。

        objectToRemove = [[objectArray objectAtIndex:10] retain];
        [objectArray removeObjectAtIndex:10];
        [objectToRemove removeFromSuperview];
        [objectToRemove release];

これにより、クラッシュが発生している理由である場合、オブジェクトがあなたの下から解放されるのを防ぐことができます。

私のシナリオが起こっているかどうかを判断する 1 つの方法は、NSZombies をオンにすることです。これは、環境変数 NSZombieEnabled を YES に設定することで実行できます。

于 2009-08-19T01:22:55.973 に答える
1

どうですか:

MyObject *objectToRemove = [objectArray objectAtIndex:10];
[objectToRemove removeFromSuperview];
[objectArray removeObjectAtIndex:10];

removeFromSuperview は、objectToRemove で保持カウントを 1 回減らします。(removeFromSuperview は、それが以前にビューに追加され、それを保持し、その保持カウントを 1 つ増やしたことを意味します)。removeObjectAtIndex は再びデクリメントします。ただし、この順序では、まだ必要なときにリリースすることはほとんどありません。(もちろん、配列に追加しても保持されるため、順序はそれほど重要ではない可能性があります)。

于 2009-08-19T07:28:08.727 に答える