質問

Objective-Cのメモリ管理についてまだ少し混乱。私は私の混乱が正確に自動解放が何を意味するかに由来だと思います。

NSString *theBackendResponse = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
NSDictionary *accountDictionary = [theBackendResponse propertyList];
[viewController setAccountDictionary:accountDictionary];

さて、私は私のビューコントローラのsetAccountDictionary方法でaccountDictionaryで何をすべきでしょうか?今私はちょうど返されているものに、インスタンス変数「accountDictionary」に設定してください。私はそれが保持いずれかに設定した後、返される1を解放すべきか?どのような私のセッターのコードブロックの外観のように、NSStringのののpropertylist方法が自動解放されることを考えるべきか。

私はtheBackendResponseを解放する場合は、

ところで、私はaccountDictionaryを失うことになりますか?私がいないと仮定...

役に立ちましたか?

解決

の呼び出し[objectInstance autorelease]は現在NSAutoreleasePoolにオブジェクトを追加します。そのプールがdrainメッセージを受信すると、プール内のすべてのオブジェクトにreleaseを送信します。これらのオブジェクトのretainCountのいずれかが0になった場合、それらはその時点で割り当てが解除されています。自動解放の目的は、「将来のある時点」をリリースするオブジェクトをマークできるようにすることです。これは、新しく割り当てられたオブジェクトを返しますが、呼び出し側は返されたオブジェクトの所有権を取得する必要がないように、それを解放するメソッドのようなもののために特に便利です。この方法は、次のようになります。

- (id)myMethod {
    id myObj = [[SomeClass alloc] init];

    ...

    return [myObj autorelease];
}
彼らは、戻り値の所有権を取るかどうそれを無視したい場合は、

myMethodの呼び出し側は戻り値をretainでしょう。現在NSAutoreleasePoolが排出されると、myObjは解放メッセージが表示されます。他のオブジェクトがそれを所有していない場合(すなわち、それにretainメッセージを送信した)、それが割り当て解除されます。

このすべてがココアメモリ管理プログラミングガイド<に説明されています/>。あなたはすでにそれを読んだとしても、それは常に他の読み取り価値はあります。

だから、あなたの質問に答えるために:

まず、あなたはtheBackendResponseを解放する必要があります。そうしない場合は、メモリリークが発生します。あなたは文字列で何accountDictionary知っている必要はありません:それはtheBackendResponseを保持しています参照を保持する必要がある場合。あなたは(theBackendResponseを介して間接的alloc経由または)その所有権を放棄しなければならないので、あなたは、それをrelease'dので、あなたはautoreleaseの所有権を持っています。

第二に、あなたは、それぞれ、そのオブジェクトまたは値への参照を保持する場合setAccountDictionary:する引数を保持またはコピーする必要があります。

:標準setterメソッドは、この(あなたがアトミックセマンティクスを必要としないと仮定した場合)のようになります
-(void)setAccountDictionary:(NSDictionary*)newDict {
  if(newDict != accountDictionary) {
    id tmp = accountDictionary;
    accountDictionary = [newDict copy]; //Since newDict may be mutable, we make a copy so that accountDictionary isn't mutated behind our back.
    [tmp release];
  }
}

また、deallocメソッドでaccountDictionaryをreleaseする覚えておく必要があります:

- (void)dealloc {
    [accountDictionary release];
    [super dealloc];
}
可能な場合はNSViewControllerを使用しているように見えるので、

、私はあなたが、その場合にはヒョウ(OS X 10.5)にしていると仮定し、あなたはおそらく@property@synthesizedゲッター/セッターを使用する必要があります。これを行うには、追加

@property (copy,readwrite) NSDictionary * accountDictionary; 

クラス@interfaceに宣言。そして、あなたのコントローラクラスの@synthesize accountDictionary;ブロックで@implementationディレクティブを追加します。

他のヒント

setアクセサメソッドは常にcopy /古い値が新しい値を所有している唯一のオブジェクトである場合には、古いものをリリースする前に入ってくる値をretain必要があります

-(void)setAccountDictionary:(NSDictionary*)newDict {
    id old = accountDictionary;
    accountDictionary = [newDict copy];
    [old release];
}
accountDictionarynewDictnewDictのカウントを保持するために呼ばれた場合は、

[accountDictionary release]の呼び出し前に[newDict copy]の呼び出しが保持カウントが0になったので、newDictを解放させるような、1だった。

私たちは、古い辞書を解放し、新しい辞書をコピーする不正なコードの例として、ます:

-(void)setAccountDictionary:(NSDictionary*)newDict {
    [accountDictionary release];
    accountDictionary = [newDict copy];
}

、次のコードを持っています:

NSDictionary *dict = [obj accountDictionary];
[obj setAccountDictionary:dict];

これは不自然だが、それはセッター、accountDictionarynewDictに同じインスタンスを参照することを示しています。保持カウントが1の場合、[accountDictionary release]ラインは0に保持カウントを減少させ、したがって、メモリからインスタンスを解放します。 [newDict copy]は現在、無効なインスタンスを参照します。

アクセサを実装するときに

アップルは、いくつかの概念について説明します。メモリ管理アクセサメソッド
あなたはObjective-Cの2.0を使用することができる場合、私はプロパティとドット構文で行くだろう。 プロパティのObjective-C 2.0の新機能で、自動アクセサの生成を提供します。
.hファイルでます:

@property (retain) NSDictionary* accountDictionary;

の実装でます:

@synthesize accountDictionary;

合成は、あなたのNSDictionaryのためのアクセサメソッドを生成します。 (あなたが独自の実装を提供したい場合は、あなたもそれを行うことができます)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top