2009-03-28 7 views
12

は、私はこのような機能を持っていると仮定します。Objective-Cメモリ管理 - オブジェクトを返すときのベストプラクティス?

- (NSSet *) someFunction { 
    //code... 
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease]; 
} 

私はこの関数を呼び出すと、私は戻り値を解放/保持何をする必要がありますか?私はそうすると思います。 someFunctionは今、次のようになりますので、

しかし、私は、自動解放を何をしていない場合:

- (NSSet *) someFunction { 
    //code... 
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil]; 
} 

をこの場合、私は私が解放したが、戻り値を保持しないために必要と仮定しています。

私の質問は、このような状況で推奨される/ベストプラクティスは何ですか? someFunctionの1つまたは他のバージョンが推奨されていますか?ありがとう。

答えて

12

Memory Management Programming Guide for Cocoaを読むのにしばらく時間を費やす必要があります。

「alloc」または「new」で始まるメソッドを使用して参照を取得するか、「copy」を含む場合は、参照を所有し、保持する必要はありません。あなたは、リリースを提供している、直接リリースまたはautoreleaseを使用しています。

他の方法で(クラスメソッドまたはwhat-have-youを介して)参照を取得した場合は、参照を所有していないため、解放する必要はありません。参照を保持する場合は、参照を保持する必要があります。

これは本当に簡単で効果的です。

+0

それはallocであり、私が信じている参照を所有していることを意味するinitではありません – cobbal

+0

はい、あなたは正しいです。それを反映する元の応答を編集する(後世のために)。 –

+5

私はそのプログラミングガイドを参照して多くのpplを参照してください。それは非常に退屈で、読むのは乾いています。 –

2

hmm ...

通常、この「方法」に従います。

+ (id)MyObj { 
    return [[[MyObj alloc] init] autorelease]; 
} 

オブジェクトを返す前に解放すると、オブジェクトは呼び出し元オブジェクトに到達する前に解放されます。これによりエラーが発生します。代わりに自動解放プールを使用して、このエラーを回避します。もともとTheocacaoのScott Stevensonによって私に紹介されました。これはObj-C 1.0のための多くの、好きな方法です。

+0

一般的な略語(HTTPBody、URLなど)でない限り、通常はメソッド名の最初の文字として大文字を使用しないでください。 –

2

2番目の例でコードを実行する唯一の理由は、メソッド名がnew、alloc、create、copyなどから始まる場合のみです。

それ以外の場合は、割り当てたオブジェクトをリリース(または自動レリース)する責任があります。最初の例は、ほとんどのことを行う正しい方法です。

呼び出し元の関数は、関数のスコープを超えて永続化したい場合は値を保持する必要がありますが、後でその呼び出しを解放する必要があります。