1

iPhone アプリに Core Data を使用しています。私の属性は保持されたプロパティで設定されています。

たとえば、「モノ」エンティティの「数値」属性:

#import <CoreData/CoreData.h>

@interface Thing :  NSManagedObject  
{
}
@property (nonatomic, retain) NSNumber * number;
@end

@implementation Thing 
@dynamic number;
@end

私のコードで Thing オブジェクトを操作するとき、次のように number プロパティを設定しています。

thing.number = [[NSNumber alloc] initWithInteger:1];

ただし、これによりメモリ リークが発生します (新しい NSNumber オブジェクトの保持カウントは、alloc とプロパティ保持により、必要な数よりも 1 つ多くなります)。

これは iPhone OS 用であるため、自分でメモリを管理したいので、自動解放プールを使用しないことを選択しています (これには、パフォーマンスが向上し、最大メモリ使用量が少なくなるという利点もあります)。

  1. 私はこのパターンが機能することを知っています (そして、すでにいくつかの SO 投稿で議論されています):

    NSNumber *num = [[NSNumber alloc] initWithInteger:1];
    thing.number = num;
    [num release];
    

    このパターンは非常に明確ですが、私は 3 行や一時変数について興奮していません。

  2. これもうまくいくと思います(ただし、SOの投稿では気づきませんでした):

     thing.number = [[NSNumber alloc] initWithInteger:1];
     [thing.number release];
    

    このパターンはあまり明確ではありませんが、2 行しか必要とせず、一時変数を使用しません。

質問
(自動解放プールを使用せずに) 保持されたプロパティに新しいオブジェクトを割り当てるための他のパタ​​ーンはありますか? ここでのベストプラクティスは何ですか?

4

4 に答える 4

3

自動解放プールの使用を除けば、これらは私が見た唯一のものです。私は自動解放をあまり警戒しません。それらは問題なく動作し、これはおそらくパフォーマンスの違いが見られないケースです。

ただし、それを本当に避けたい場合は、ここで適用できるベスト プラクティスは「最小の驚きの原則」です。最初の慣用句はほとんどのサンプル コードに含まれているため、コードを保守する人のために余分な行を削除する必要があるようです。

于 2009-11-12T07:18:33.660 に答える
2

それらを使用するかどうかにかかわらず、自動解放プールはデフォルトで既にコードを囲んでいます。個人的には、自動解放されたオブジェクトを使用しないと、パフォーマンスが大幅に向上するとは思いません。自動解放プールとガベージ コレクションは 2 つの異なる概念であり、前者の方がはるかに単純であることに注意してください。自動解放されたオブジェクトを使用したくない唯一の場所は、大きなループです。

記録のために、2 番目のパターンも問題なく動作するはずです。

于 2009-11-12T07:16:42.883 に答える
1

タイトなループで多数のオブジェクトを作成する場合を除き、自動解放プールが大幅に多くのメモリを使用することはありません。

2 行または 3 行のコードを記述するか、単に自動解放プールを使用するかのいずれかのオプションがあると思います。

個人的には、特定のパフォーマンスやメモリの問題が発生しない限り、自動解放プールを使用することは間違いありません。

于 2009-11-12T07:16:08.637 に答える
1

多くのオブジェクトでは、自動解放されたインスタンスを返すメソッドを直接使用できます。例として、私は通常、あなたのコード スニペットに相当するものを次のように書きます。

thing.number = [NSNumber numberWithInt:1];

プロパティは NSNumber を保持しているため、プロパティの使用が終了したら、後で解放する必要があることに注意してください。

とにかく、自動解放されたオブジェクトを返すコンストラクターがないためにこれが当てはまらない場合、パターン 1 は間違いなく正しいです。

代わりに、パターン 2 は次の理由で正しくないように思えます。最初に NSNumber をプロパティに割り当ててから、プロパティを解放します。ただし、プロパティによって保持されていたものではなく、割り当てた NSNumber を解放する必要があります (これは後で、プロパティの操作が完了したときにもう一度行います)。パターン 2 の最終的な影響は、メモリ リーク (割り当てられた NSNumber が解放されない) と、プロパティに NSNumber が含まれていないこと (最初に保持してから解放したため) です。

于 2009-11-12T09:01:06.787 に答える