10

私はメモリ管理に関するすべてのドキュメントを調べていますが、何かについて少し混乱しています。

@propertyを使用すると、オブジェクトのゲッター/セッターが作成されます。

.h:@property(保持、非アトミック)NSString * myString

.m:@synthesize myString

私はそれを理解していますが、私が混乱するのは自己の使用です。ブログや本によって構文が異なります。私は見た:

myString = [NSString alloc] initWithString:@"Hi there"];

また

self.myString = [NSString alloc] initWithString:@"Hi there"];

それからdeallocで私は見る:

self.myString = nil;

また

[myString release];

また

self.myString = nil;
[myString release];

このサイトで、誰かが自己を使用すると保持カウントに別の増分が追加されると述べましたか?それは本当です、私はそれをどこにも見たことがありません。

提供されている自動ゲッター/セッターは自動リリースされますか?

これをすべて行う正しい方法はどれですか?

ありがとう!

4

3 に答える 3

18

ドット構文を使用していない場合は、セッターまたはゲッターを使用していません。

次のことは、プロパティがどのように宣言されているかによって異なります。

次のようなものを想定しましょう。

@property (nonatomic, retain) Article *article;
...
@synthesize article;

記事に何かを割り当てる

self.article = [[Article alloc] init];

alloc / initによって返されたインスタンスを過剰に保持し、リークを引き起こします。これは、記事のセッターがそれを保持し、以前のインスタンスを解放するためです。

したがって、次のように書き直すことができます。

self.article = [[[Article alloc] init] autorelease];

これを行う

article = [[Article alloc] init]; 

も大丈夫ですが、記事がすでにインスタンスへの参照を保持している可能性があるため、リークが発生する可能性があります。したがって、事前に値を解放する必要があります。

[article release];
article = [[Article alloc] init]; 

メモリの解放は次の方法で実行できます

[article release];

またはと

self.article = nil;

最初のものはフィールドに直接アクセスし、セッター/ゲッターは関与しません。2つ目は、セッターを使用してフィールドにnilを設定します。nilに設定する前に現在のインスタンスがある場合は、これによって現在のインスタンスが解放されます。

この構成

self.myString = nil; 
[myString release];

あまりにも多く、実際にはリリースをnilに送信します。これは無害ですが、不必要でもあります。

ドット構文を使用して帽子を精神的にマッピングする必要があります。アクセサメソッドを使用しています。

self.article = newArticle
// is
[self setArticle:newArticle];

myArticle = self.article;
// is
myArticle = [self article];

読むことに関するいくつかの提案、Appleによるすべての公式文書:

Objective-Cプログラミング言語

メモリ管理プログラミングガイド

于 2011-05-05T19:55:10.670 に答える
1

セッターを作成すると、次のretainようなものが作成されます。

- (void)setString:(NSString *)someString {
    if (someString != string) {
        [string release];
        [someString retain];
        string = someString;
    }
}

セッターを使用しない場合、新しい値はその保持を取得しません。その文字列を「所有」することはありません。すべての参照であるため、元の文字列が解放されると、null参照に直面する可能性があります。につながりEXC_BAD_ACCESSます。セッターを使用すると、クラスにその値のコピーが確実に含まれるようになります。つまり、新しい値の保持カウントが増加します。(ゲッターの使用はOOPの規則であることに注意してください。つまり、部外者がivarに直接触れることはできません。また、ゲッターでは値を変更できます。たとえば、ivarがNSMutableArrayの場合はNSArrayを返します)。

セッターを使用するべきではありませんautorelease。Appleはサンプルコードでこれを使用していますが、セッターは何百万回も呼び出される可能性があることに注意してください。これらのオブジェクトはすべて同じ自動解放プールに入るので、独自のオブジェクトを作成したり、定期的にフラッシュしたりしない限り、プールには大量の要素があり、すべて不要ですが、RAMを使用しています。単純にするとはるかに良いrelease

Deallocについては、そのセッターをさかのぼってください。直接送信する場合release、それは明らかです—そのオブジェクトを解放します。しかし、あなたが書く場合self.string = nil;、あなたがしていることはこれです:

  1. nil値は同じではないため、ifブロックに入ります
  2. 古い値を解放します—やりたいこと
  3. あなたはretainnil:nilへのメッセージは何もしません、そしてあなたはクラッシュしません
  4. メモリを消費しないnilを文字列に設定します。文字列は、実質的に空になります。

慣例として、私releaseは自分のdeallocメソッドで使用します。これは、releaseより最終的なようでありdealloc、オブジェクトが受け取る最後のメソッド呼び出しであるためです。self.string = nil;viewDidUnloadとメモリ警告メソッドで使用します。

お役に立てれば!

于 2011-05-05T20:12:27.283 に答える
1

Nickの答えに加えて-合成されたゲッター/セッターは自動リリースを提供しません(ところで、これを行うことの大きなアイデアは何ですか?まあ、ファクトリーとしてゲッターを使用できますが、ObjectiveCでは一般的な方法ではありません)。

それからdeallocで私は見る:

self.myString = nil;

また

[myStringリリース];

また

self.myString = nil; [myStringリリース];

Deallocでは、使用しているリリースの形式は実際には重要ではありません。しかし、良い方法は、フィールドを解放するときにフィールドをゼロにすることです:)私self.myString = nil;はdeallocで使用することを好みます

于 2011-05-05T20:13:41.957 に答える