@property/@sinthesize question
-
29-10-2019 - |
質問
私はメモリ管理に関するすべてのドキュメントを調べていますが、何かについて少し混乱しています。
@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];
このサイトで、誰かが自己を使用すると、保持数に別の増分が追加されると述べましたか?それは本当ですか、私はそれをどこにも見ていません。
AutorEleaseが提供される自動ゲッター/セッターはありますか?
これらすべてを行う正しい方法はどれですか?
ありがとう!
解決
DOT構文を使用していない場合は、セッターまたはゲッターを使用していません。
次のことは、それはプロパティがどのように宣言されているかによって異なります。
このようなものを仮定しましょう:
@property (nonatomic, retain) Article *article;
...
@synthesize article;
割り当て 記事に何か
self.article = [[Article alloc] init];
Alloc/initによって返されたインスタンスをオーバーレットし、漏れを引き起こします。これは、記事のセッターがそれを保持し、以前のインスタンスをリリースするためです。
だからあなたはそれを次のように書き直すことができます:
self.article = [[[Article alloc] init] autorelease];
これをしています
article = [[Article alloc] init];
また、OKですが、記事はすでにインスタンスへの参照を保持する可能性があるため、リークが含まれる可能性があります。そのため、事前に価値を解放する必要があります:
[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プログラミング言語
メモリ管理プログラミングガイド
他のヒント
あなたが作成するとき retain
セッター、あなたはこのようなものを作成しています:
- (void)setString:(NSString *)someString {
if (someString != string) {
[string release];
[someString retain];
string = someString;
}
}
セッターを使用しない場合、新しい値が保持されていません。その文字列を「所有」していません。すべての参照であるため、元の文字列がリリースされた場合、null参照に直面している可能性があります。につながります EXC_BAD_ACCESS
. 。セッターを使用すると、クラスにその値のコピーがあることが保証されます。そう、新しい値の保持数を増やします。 (Getterを使用することはOOPの慣習であることに注意してください。部外者はIvarに直接触れることはできないはずです。また、ゲッターでは価値を変更することができ、たとえばIvarがnsmutablearrayである場合にnsarrayを返すことができます)。
あなたはすべきではありません autorelease
セッターでは、Appleがサンプルコードで使用していますが、留意すべきことは、セッターが潜在的に何百万回も呼ばれていることです。これらのオブジェクトはすべて同じAutoreleaseプールに入ります。そのため、独自のオートレリーズプールや定期的にフラッシュしない限り、プールに大量の要素があります。簡単にははるかに優れています release
.
deallocについては、そのセッターを通過します。あなたが送る場合 release
直接、それは明らかです。そのオブジェクトをリリースします。しかし、あなたが書くなら self.string = nil;
, 、あなたがしていることはこれです:
- nil値は同じではないので、
if
ブロック - あなたは古い価値、つまりあなたがしたいことをリリースします
- 君は
retain
nil:nilへのメッセージは何もしません、そしてあなたはクラッシュしません - メモリを取り上げないnilを文字列に設定します。
慣習の問題として、私は使用します release
私の中で dealloc
方法、なぜなら release
もっと最後のようです dealloc
オブジェクトが受信する最終的な方法です。私が使う self.string = nil;
ViewDidunloadおよびメモリ警告方法。
お役に立てれば!
ニックの答えに加えて、合成されたゲッター/セッターはオートリリースを提供しません(ところで、これを行うという大きなアイデアは何ですか?
それから、deallocではわかります:
self.mystring = nil;
また
MyStringリリース];
また
self.mystring = nil; [MyStringリリース];
Deallocでは、使用しているリリースの形式は実際には問題ではありません。しかし、良い方法は、それらをリリースするときにあなたのフィールドをいないことです:)私は使用することを好みます self.myString = nil;
deallocで