2011-02-02 10 views
1

次の例を見て:後で返されるinstance methodeにオブジェクトを割り当てるための推奨されるアプローチは何ですか?例えば

CODE1

-(NSString*)getString{ 
    return [[[NSString alloc] initWithFormat:@"test"] autorelease]; 
} 

-(void)printTestString{ 
    NSString *testStr = self.getString; 
    [testStr retain] 
    NSLog(@"%@",testStr); 
    [testStr release] 
} 

CODE2

-(NSString*)getString{ 
    return [[NSString alloc] initWithFormat:@"test"]; 
} 

-(void)printTestString{ 
    NSString *testStr = self.getString; 
    NSLog(@"%@",testStr); 
[testStr release]; 
} 

コード1とコード2は、有効なコードスニペットであるべきで、何のリークは表示されないはずです。

コード1は自動解放を使用するため、戻り変数はprintTestStringに保持され、使用後に解放されます。オートレリーズのためにここに小さなオーバーヘッドがあります。

コード2は、getStringのNSStringを解放しないため、使用後に解放する必要があります。 autoreleaseが使用されていないため、あなたは書き込む必要が少なく、オーバーヘッドはありません。

そこで使用されているデファクトスタンダードアプローチはどちらですか?

私は自分自身に尋ねていました。 getStringでの自動解放と

[testStr retain] 
で保持

は、自動解放プールは、その文字列がなくなってしまう

NSString *testStr = self.getString; 

後に変数権利を離したときに、問題がある可能性があります。それは可能ですか、コンパイラはそのようなことを防ぐのですか?

おかげ

-Sebo

+1

@MusiGenesisここに私の推奨されるアプローチがあります:あなたがObj-Cを好きでないなら、それをプログラミングせずに人々のObj-Cの質問に答えないでください。 – jakev

+0

@ JakeVAありがとう! – Sebo

答えて

2

これを行う:

-(NSString*)getString{ 
    return [[[NSString alloc] initWithFormat:@"test"] autorelease]; 
} 

-(void)printTestString{ 
    NSString *testStr = self.getString; 
    NSLog(@"%@",testStr); 
} 

あなたのgetStringメソッドがprintTestStringが保持またはそれを解放する必要がないことを意味NSStringのを、自動解放。 getStringの自動リース処理は理にかなっています。これは、オブジェクトを割り当てたためオブジェクトの '所有者'です。私はObjective-Cのメモリ管理規則を勉強することをお勧めします。

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH

+0

大丈夫ですが、私はまだautoreleaseを使用する必要があります。私はそれを使わないことで解決できると思った。私はそうしなければならないようだ。私のコードが可能な限り効率的なとき、私は本当にそれが好きです。 – Sebo

+0

する必要はありませんが、オブジェクトを作成して返すメソッドがある場合は、そうする必要があります。彼らのコードができるだけ効率的であると誰もが気に入っています。 autoreleaseを呼び出すと、作成していない既存のプールに追加されます(そうしない限り)。そのプールが排水されると、オブジェクトは解放メッセージを受け取ります。それは唯一のオーバーヘッドですが、実際にはそれほど大きな問題ではありません。 – jakev

+0

OK JakeVA、ありがとうございます。私は確信してautoreleaseに固執しています。 – Sebo

2

ジェイクの答えは、ほぼすべてあなたがメソッドからオブジェクトを返す必要があります状況のために正しいですが、自動解放されていない何かを返したいかもしれない場合があります。

あなたはその名を 「のalloc」または「新しい」または で始まるメソッドを使用して作成し 場合は、オブジェクトの所有権を取る:Memory Management Programming Guide(Mac版が、彼らは同じルールだ)から、 「コピー」(たとえば、alloc、 newObject、またはmutableCopy)が含まれている場合、または に保持メッセージを送信した場合。 戻りオブジェクトの値は、あなたは彼らが、オブジェクトの作成または オブジェクトコピーされない限り、これらの値は を自動解放返す ていることを確認してくださいあなたのメソッドや関数で

Coding Guidelines for Cocoaからも

、メソッド(new、alloc、copy とその亜種) の "Autoreleased"は、このコンテキストが必ずしも を意味するとは限りません。オブジェクトが明示的に である必要があります。つまり、 autoreleaseを の直前に返すことです。一般的な意味では、 は、戻り値が呼び出し元によって解放された ではないことを意味します。パフォーマンス上の理由から

、それは短い期間内に頻繁に 実行される可能性がありますこと、特にコード で、メソッドの実装に オブジェクトを自動解放 いつでもすることができますを避けるために お勧めです。 の例は、 と未知のループであり、潜在的に高いループカウントとなる。

したがって、方法は接頭allocまたはnewを含む、または慣例によって単語copyを含むものは、あなたが自動解放されていないオブジェクトを返す必要があります。実際、Clangスタティック・アナライザーはこの規則を理解しており、これらの命名規則に従ったメソッドから返される非自動解放オブジェクトを前提としています。

私は、自動解放されたオブジェクト(自動解放プールなどを管理したくないタイトなループ)を返さないことを望む状況では、接頭辞newを使用しました。繰り返しますが、オートレリースされたオブジェクトを返すことは、ほとんどすべての場合に推奨されることですが、避けたい場合があります。

関連する問題