Apple の The Objective-C Programming Language p. 18 では、自己参照とインスタンス参照を使用して変数を設定することを区別しています。例: myInstance.value =10; 自己値 = 10; 1. これら 2 つは値という名前の異なるプロパティを設定しますか? 2. value という名前のプロパティを持つインスタンスが複数ある場合、どのように自己機能しますか? また、「self. を使用しない場合は、インスタンス変数に直接アクセスすることになる」とも主張しています。これは、myInstance.value =10; を使用すると、アクセサーが呼び出されないことを意味します。KVOは機能しません。これは本当ですか?3. @Property と @Synthesize (ガベージ コレクションを使用) を使用して、異なるインスタンスのプロパティを設定する適切な方法は何ですか? そして、自己参照は何に役立ちますか?数値例が役に立ちます。
4 に答える
1 - これら 2 つは値という名前の異なるプロパティを設定しますか?
いいえ、 self.value と myInstance.value を区別するときにガイドが言っていることを誤解していると思います。どちらの場合も、セッター関数 (つまり、setValue:) が呼び出されます。
self を使用して、独自のプロパティにアクセスします (つまり、作成したクラスの関数内からプロパティを参照します)。お気に入り:
@interface MyObject : NSObject
@property( nonatomic ) NSInteger value;
- (void) doSomething;
@end
@implementation MyObject
@synthesize value;
- (void) doSomething
{
self.value = 10;
}
@end
一方、 myInstance を使用して、そのクラスの外部から他の変数にプロパティを設定します。
MyObject* anObject = [[MyObject alloc] init];
anObject.value = 10;
2 - 値という名前のプロパティを持つ複数のインスタンスがある場合、どのように自己機能しますか?
そうではありません。上記を参照。
また、「self. を使用しない場合は、インスタンス変数に直接アクセスすることになる」とも主張しています。これは、myInstance.value =10; を使用すると、アクセサーが呼び出されないことを意味します。KVOは機能しません。これは本当ですか?
いいえ、self.value と myInstance.value はどちらもアクセサー (この場合は setValue:) を呼び出し、KVO は機能します。このアサーションが意味することは、アクセサーを使用せずに独自のクラス内から ivar にアクセスすると、KVO が機能しないということです。
@interface MyObject : NSObject
@property( nonatomic ) NSInteger value;
- (void) doSomething;
@end
@implementation MyObject
@synthesize value;
- (void) doSomething
{
self.value = 10; // This invokes the accessor, and KVO works.
value = 10; // This just sets the instance variable, and KVO won't work.
}
@end
@Property と @Synthesize (ガベージ コレクションを使用) を使用して、異なるインスタンスのプロパティを設定する適切な方法は何ですか? そして、自己参照は何に役立ちますか?数値例が役に立ちます。
上記のように、インスタンス名を使用します。self は、クラス内のプロパティにアクセスするためにのみ使用されます。上記の例。
自己を理解する最良の方法は、それがどのように実装されているかを考えることです。すべてのメソッド呼び出しで隠された引数として、メソッド-[UIView drawRect:]に次のようなac関数の実装があります。
BOOL drawRect:( UIView * self, SEL _cmd, NSRect r ) { }; // of cause : is not legal in c
メソッドの呼び出しは(動的ルックアップを無視して)少し似ています
UIView * v = ...
NSRect r = ...
drawRect:( v, @selector(drawRect:), r );
したがって、drawRect:実装でプロパティを呼び出すと、selfと呼ばれる非表示のオブジェクトパラメータに対してそれを実行します。
インスタンス変数に直接アクセスすると、KVOが機能しなくなりますが、たとえば初期化するときに、それが必要になる場合があります。
ガベージコレクションと言うときに自動参照カウントを意味する場合、ほとんどの場合、オブジェクトを強力またはコピーする必要があります。コピーを使用する不変の文字列は保持に変換されます。可変の場合は、コピーを保護する必要があります。オリジナルがあなたの下で変更されることに対して。
strongの潜在的な問題の1つは、循環参照になってしまう可能性があることです。循環参照をたどると、元のオブジェクトに戻って、各オブジェクトが間接的にそれ自体を保持し、オブジェクトが前にそれ自体を解放しなければならないというキャッチ22の状況になります。それはそれ自体を解放することができます。したがって、これらの状況では、weakを使用する必要があります。通常、どちらのオブジェクトが他のオブジェクトを概念的に所有しているかを考えることで、誰を保持し、誰を弱くするかを検討できます。
非オブジェクトの場合は、割り当てを使用する必要があります。
私の大きな問題は、ivar とプロパティが異なる名前を持つ場合、特に複数の ivar を使用してそれらを結び付ける方法でした。
プロパティの名前がivarの名前と一致しない場合、新しいivarが合成されることが最終的にわかりました。これは、宣言された ivar ではなく、self.propertyname (オブジェクト内) または object.propertyname (オブジェクト外) によってアクセスされます。
ivarとプロパティの異なる名前を結び付けるには、
@synthesize プロパティ名 = ivarname のようにそれらを同一視します。
おかげで
http://blog.ablepear.com/2010/05/objective-c-tuesdays-synthesizing.html
self.property
クラス内で自分自身を参照するために[self method];
厳密に使用されます。オブジェクト自体を 以外で参照することはありませんself
。
逆に、オブジェクトのインスタンスを使用して、別のクラスのオブジェクトを参照します。たとえば、次のような方法でa UIImageView
from myを参照します。viewController
UIImageView* imgView = [[UIImageView alloc] init];
[imgView setFrame:CGRectMake(0,0,320,480)];
しかし、私が呼び出した UIImageView のサブクラスを編集していた場合、rotatingImageView と言います。
@implementation rotatingImageView
-(id)init
{
//Super instantiation code that I don't remember at the moment goes here
[self setFrame:CGRectMake(0,0,320,480)];
}
これはメソッドのほんの一例です。
ここでも、self を独自のクラス内で厳密に使用し、他の変数を使用して別のクラスのインスタンスを参照します。
それが理にかなっていることを願っています。