3

いくつかのオブジェクトを作成し、それらを配列に追加するとします。

House *myCrib = [House house];
House *johnHome = [House house];
House *lisaHome = [House house];
House *whiteHouse = [House house];

NSArray *houses = [NSArray arrayWithObjects: myCrib, johnHome, lisaHome, whiteHouse, nil];

通常、すべてのHouseオブジェクトの保持カウントは2ですが、自動解放されるのは1回です。しばらくしてmyCrib、所有者でなくても、リリースすることにしました—保持または初期化したことはありません。

[myCrib release];

保持カウントがゼロになり、オブジェクトの割り当てが解除されます。今の私の質問は、この違法なアクションによってアプリが誤って動作したり、クラッシュしたりするのでしょうか、それともNSArray単にオブジェクトをリストから削除して悪い結果をもたらすのでしょうか。

オブジェクトのリストを維持する方法を探していますが、リスト自体を維持したいと思っています。一部のオブジェクトが消えたら、そのオブジェクトへの参照を配列から適切かつ自動的に消えさせたいと思います。サブクラス化またはラッピングを考えていNSArrayます。

ありがとうございました。

4

5 に答える 5

6

私の質問は、この違法なアクションによってアプリが誤って動作したり、クラッシュしたりするのでしょうか、それともNSArrayがリストからオブジェクトを削除して悪い結果をもたらすのでしょうか。

これで、配列に無効なオブジェクトポインタが含まれます。ポインタを見ただけではポインタが無効であると判断する方法はなく、オブジェクトの割り当てが解除されたことが配列に通知されません。問題は配列にあるのではなく、結局のところ、問題はオブジェクトを不適切に解放するコードにあります。そうです、その悪いポインタが原因でアプリケーションがクラッシュしたり、正しく動作しなかったりする可能性があります。いいえ、NSArrayは問題を検出して処理しません。

オブジェクトのリストを維持する方法を探していますが、リスト自体を維持したいと思っています。一部のオブジェクトが消えたら、そのオブジェクトへの参照を配列から適切かつ自動的に消えさせたいと思います。

リスト内のオブジェクトがすべて共通クラスのインスタンスである場合は、オブジェクトを保持/解放してリストから追加/削除する独自のメモリ管理メソッドを定義するか、複数のリストが存在する可能性がある場合に適切な通知をブロードキャストできます。この目的のために-retainと-releaseをオーバーライドすることもできると思いますが、それを実行する前に、それについて長く懸命に考え、実行する場合は十分に文書化してください。他の開発者が期待するようなものではありません。

別のオプションはコアデータかもしれません。管理対象オブジェクトをオブジェクトグラフから削除すると、関係から消えます。厳密に言えば、多対数の関係はリストではなくセットですが、違いはあなたの目的にとっては問題ではないかもしれません。

更新:質問にタグを付けていないことに気づきましたios。MacOS Xで作業している場合は、NSPointerArrayを確認する必要があります。ガベージコレクションを使用する場合、弱参照を使用し、収集されたオブジェクトへの参照をnull参照に置き換えるようにNSPointerArrayを構成できます。これはまさにあなたが探しているように見えるものです。

于 2011-05-13T16:22:45.377 に答える
3

オブジェクトのリストを維持する方法を探していますが、リスト自体を維持したいと思っています。一部のオブジェクトが消えたら、そのオブジェクトへの参照を配列から適切かつ自動的に消えさせたいと思います。NSArrayをサブクラス化またはラップすることを考えています。

私が正しく理解していれば、必要なのは弱参照の配列です。次に、この投稿を読むことに興味があるかもしれません。

于 2011-05-13T16:52:46.633 に答える
3

所有者でない場合は解放しないでください。myCribこれを行うと、メモリ管理ガイドラインに違反し、コードの保守が非常に困難になります。私はあなたがどんな種類の状況でも絶対にこれを決してしてはいけないということを十分に強調することはできません。 あなたはクラッシュを求めています。配列はオブジェクトの所有権を宣言しており、いかなる方法でもその所有権を破壊してはなりません。

したがって、ここでの答えは次のとおりです。コードは完全に間違っているため、修正する必要があります。修正できない場合は、オブジェクトの所有権を損なうことなく同じ効果を実現する別の方法が見つかるまで、それを破棄して最初からやり直し、書き直してください。私はそれが可能であることを保証します。


必要なのが弱い参照配列である場合、これを行うにはいくつかの方法があります(これは数日前に尋ねられたばかりです)。

  1. NSPointerArray-ポインタを弱く参照します。ガベージコレクションを使用すると、それらは自動ゼロ調整されます(つまり、オブジェクトの割り当てが解除されると、ポインターが削除されます)。残念ながら、これはiOSでは利用できません。
  2. CFMutableArrayRef-カスタムretainreleaseコールバックを指定することも、まったく指定しないこともできます。それらを省略すると、配列には含まれているオブジェクトが保持されなくなります。ただし、これにより、オブジェクトの割り当てが解除されたときにポインタが自動的に削除されることはありません。
  3. DDAutozeroingArray-NSMutableArray先日私が書いたサブクラスは、MacOSとiOSの両方で機能する弱参照および自動ゼロ調整配列を提供します。ただし、これは最後の手段としてのみ使用することを強くお勧めします。あなたが探していることをするためのおそらくはるかに良い方法があります。 https://github.com/davedelong/Demos
于 2011-05-13T16:42:38.760 に答える
1

ここでクラッシュを求めています。あなたNSArrayはまだ存在しなくなったオブジェクトへの参照を持っています-そしてそれがしばらくして何を指しているのか誰が知っていますか?

サブクラス化NSArrayも答えではないかもしれません。これはクラスクラスターであり、要するに、あなたが望むよりもサブクラス化するのが難しいことを意味します。

これをどのように実装するか完全にはわかりません。配列が割り当て解除されようとしているときに通知を送信する要素のようなもので、配列がそれを取得します。オブジェクトをリークしたり、過剰にリリースしたりしないように注意する必要があります。

于 2011-05-13T16:30:34.347 に答える
0

私はラッパークラスを作成しました—私のコードではそれはコントローラーと呼ばれています—それは私のために(可変の)配列を維持します。配列を直接使用する代わりに、ビューコントローラー(必要な場所)でコントローラークラスを初期化します。

私にとって無効なコードはありません。:-p

于 2011-05-14T10:32:42.883 に答える