文法へのアクセスのインスタンス変数には?(Objective-C)
-
28-10-2019 - |
質問
何かに適切な構文にアクセスするために、インスタンス変数にObjective-C?
としてこの変数:
@interface thisInterface : UIViewController {
NSMutableString *aString;
}
@property (nonatomic, retain) NSMutableString *aString;
この合成に成功した。
いたい場合はアクセスすると、まず思い配分および初期化します。有するプログラムにObjective-Cヶ月現在、二つの異なる形態の構文です。私は見た人だけで aString = [[NSMutableString alloc] initWithString:@"hi"]
, し、配分の文字列のようにする;私も始まで self.aString
その後進を初期化する方法についてそのivar.これやって直そうとしていることが何よりも適切な方法を初期化するインスタンス変数が前例のな状況にありましたが、EXC_BAD_ACCESS誤差からです。後prependingの self.
ももんが表示されます。
の場合はご容赦ことが重複した質問ですが、読んだ後にも載ったら帰ってきてくださいねっても不思議です。私を学習しようとしている、適切な構文とObjective-Cが込めると感じます適切なずさんな.
解決
財産を宣言した場合 @synthesize
.mファイルでは、このように設定するだけです。
self.aString = @"hi"; // or [[NSMutableString alloc] initWithString:@"hi"];
使用 self.varName
あなたの財産宣言が実際に行っていることを利用してください - それは新しい価値の保持を処理します(あなたの財産には retain
属性)、あなたのために古い値などをリリースします。
あなたがするなら:
aString = someValue;
...あなたはにあった元の価値を漏らしているかもしれません aString
, 、使用せずに self.aString
プロパティを介して変数に直接アクセスしています。
他のヒント
間の違いに注意してください self->varName
と self.varName
最初はです ポインター アクセス。 2番目はです 財産 アクセス。
なぜそれが重要なのですか?ポインターアクセスは直接です。一方、プロパティアクセスはゲッターとセッターを利用しています( @synthesized
か否か)。さらに、利便性として、@synthesizedアクセサはあなたのためのメモリマージメントを処理します(つまり、使用する場合 self.varName = ...;
)、 一方 varName = ...;
それが言っていることだけ、つまり割り当て - >(exc_bad_accessエラーの説明があります)。
構文的に、両方のフォームが正しいです。意図をよりよく伝えたい場合は、使用してください self->varName
ポインターと直接作業して使用したいとき self.varName
あなたが利用したいとき @property
快適。
すべての可能な組み合わせ(私は思う)OKSとBADSは正しいときだけです aString
プロパティにはあります retain
属性:
@property (nonatomic, retain) NSMutableString *aString;
そう:
1
aString = [[NSMutableString alloc] init]; //OK:
これは問題ありませんが、アストリングが無効なオブジェクトを指しているわけではない場合のみ、またはそのオブジェクトへの参照を失い、それをリリースすることができないため漏れます。
2
aString = [NSMutableString string]; //BAD
あなたが迷っていると思われるので悪い(あなたがそれをそのように宣言したように)、あなたはそれを保持していないので、あなたは将来exc_bad_accessを確実に取得するでしょう
3
aString = [[NSMutableString string] retain]; //OK
最初のアプローチと同じですが、迷っている場合にのみ有効なオブジェクトを指していない場合のみです。ただし、最初は使用します。
4
aString = [[[NSMutableString alloc] init] autorelease];//BAD
2番目のアプローチと同じ。
5
self.aString = [[NSMutableString alloc] init]; //BAD!!
あなたがそれを2回保持しているので悪いので、それはメモリリークにつながります
6
self.aString = [[NSMutableString string]; //******GOOD!******
これはおそらく最も安全です。プロパティセッターによって保持され、セッターを使用しているため、攻撃によって指摘された可能性のある他のオブジェクトは適切にリリースされます
7
self.aString = [[NSMutableString string] retain]; //BAD
これは2回保持されます。
8
self.aString = [[[NSMutableString alloc] init] autorelease];//Ok
これも大丈夫ですが、この長いアプローチではなく便利な方法を使用します:)
自分が何をしているのかを知っていれば、#1と#3のオプションが完全に良いことに注意してください。実際、私は#6よりもはるかに頻繁にそれらを使用します
個人的に好みで使用に self.
構文です。そうすると、そのインスタンス変数のみならず、その他の変数の範囲が失われますが、そのNSAutoreleasePoolは水気を切る。しかし、正しい使い方や、受信している場合EXC_BAD_ACCESS誤りではないししますので使用しないでアクセス self.
.しかし、これallocで、いずれかの方を選択したアクセス変数を、そのままで一貫したまたは届きます。
この助けになっていますよ。
以外は常にアクセターを使用してください init
, dealloc
そしてアクセサ自身で。これを行うと、あなたが説明しているような頭痛が多くなります。また、ivarsにあなたの財産とは違うものに名前を付けます(_foo
, foo_
, mFoo
, 、 だがしかし foo
).
self.foo
まったく同じです [self foo]
. 。メソッドを呼び出します foo
. self.foo = x
まったく同じです [self setFoo:x]
. 。メソッドを呼び出します setFoo:
. 。プロパティを合成した場合 foo
として retain
変数、それは次のように見えます:
@synthesize foo = foo_;
- (void)setFoo:(id)value {
[value retain];
[foo_ release];
foo_ = value;
}
これにより、の古い価値が正しくリリースされます foo_
, 、新しいものを割り当てて保持します。
foo = x
(仮定します foo
ivarです)はどんな方法も呼びません。なし。ポインターの値を割り当てます x
ポインターに foo
. 。もしも foo
保持されたものを指して、漏れています。割り当てた新しい値が保持されない場合、後でクラッシュします。
これに対する解決策は、可能な場合は常にアクセターを使用することです。
また。
DOT構文を使用すると(一部に)クリーナーであり、同等のものにコンパイルされます。すなわち self.iVar
と同じです [self iVar]
と self.iVar = aValue
と同じです [self setIVar:aValue];
self.aString
構文砂糖です [self aString]
. 。プロパティを合成するだけです -aString
と -setAString:
方法(些細な感情ではないが、それを選択したプロパティに応じて)。
ここで問題は、を使用するかどうかです .
表記。使用しないことをお勧めします。なんで?まず、Objective-CがCに追加されることを目的としていることを知ってください。これは、すべての有効なCコードも有効なObjective-Cコードであることを意味します。
次に、彼らがドット表記で何をしたかを見てください。最後の声明はもう保持されません。 C構造のフィールドへのアクセスとObjective-Cメソッドの送信を区別しません。
ドット表記を使用しないでください。 [self ..]を使用することを好みます。