-2

カスタムクラスへのローカルポインターがある場合、そのポインターをクラスレベルのNSDictionary変数に格納し、最初の作成スコープが終了した後にそれを使用するにはどうすればよいですか。

作成したクラスがスコープ外になるまで、newによって作成されたメモリを保持するようにコンパイラに指示するにはどうすればよいですか?

これは、問題の変数のスコープを表すsudoコードです。

Class {

    NSMutableDictionary* allElements;

    SomeFunction {

       InnerClosure1 {

       DefaultElement* element = [DefaultElement new];
       [allElements setObject:element forKey:@:"Foo"];

       }

       InnerClosure2 {

          DefaultElement* element = [allElements objectForKey:@"Foo"];

      }
}

問題は、ポインタを辞書に入れようとした後にこのエラーが発生することです。

[__NSDictionaryI setObject:forKey:]:認識されないセレクターがインスタンス0x94421d0に送信されました2013-01-31 23:35:32.575 Muskoka-Domicile [1371:19d03] *キャッチされない例外'NSInvalidArgumentException'、理由:'-[__NSDictionaryIsetObjectによるアプリの終了:forKey:]:認識されないセレクターがインスタンス0x94421d0'に送信されました

カスタムクラスの所有権を譲渡することと関係があるのではないかと思います。

編集 NSMutableDictionary*をNSDictionaryに初期化したことがわかります...

4

1 に答える 1

2

ローカル ポインターが失われる可能性があります。関心があるのは、指しているメモリ (オブジェクト) のチャンクです。

オブジェクトを NSDictionary に追加すると、そのオブジェクトはディクショナリによって保持されます。scope1 を離れることができ、オブジェクトは問題ありません。実際、arc を使用していない場合、要素を辞書に追加した後、通常は への呼び出し[element release]のバランスを取るために呼び出しますnew

後でオブジェクトをディクショナリから取り出すときは、一時ポインタ (要素) をオブジェクトのメモリ アドレスで更新するだけです。「Scope2」では、オブジェクトを作成していないため、完了しても解放しません。

物事を明確にするのに役立つことを願っています。

編集/更新 私は注意すべきです、あなたのコードは基本的にそのまま正しいです。オブジェクトを辞書に入れたい場合は が必要なNSMutableDictionaryので、コードの先頭にそれらの 1 つを作成します。次に、setObject:forKey:notを呼び出しますsetValue。それはあなたのためにトリックをするはずです。(DefaultElement *)要素をディクショナリから引き出すときに警告を抑制するために、キャストを追加する必要がある場合があります。

于 2013-02-01T00:41:35.930 に答える