iOSベース(11)-属性とメンバー変数はいったい何を指していますか?

3972 ワード

属性とメンバー変数はiOSの開発を始めたばかりで、特にsetterとgetterメソッドを手動で合成する必要はありません.
1.メンバー変数
メンバー変数はC++のクラスのメンバーに似ています.クラスの初期化時に同じメモリに格納される変数で、クラスと結合されています.コードは次のとおりです.
@implementation ClassA {
    NSString *str;    //       
    NSInteger count;    //      
    int index;    //          
}
...
@end

Object-Cは動的言語でruntime関数にもう一つのclass_addIvarはクラスにメンバー変数を追加できますが、クラス申請メモリの割り当てと登録の間に追加する必要があります.そうしないと、クラスがすでにメモリに存在している場合は、クラスにメンバー変数を追加することはできません.この関数には説明があります.
This function may only be called after objc_allocateClassPair and before objc_registerClassPair. 
Adding an instance variable to an existing class is not supported.

2.属性propertyはシンタックス(Syntactic sugar)であり、主に属性を明らかにしている.copy、strong、assignなど、さまざまな修飾語を加えることもできます.例を挙げます.
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *address;
はクラス割り当てのメモリには存在しません.ハッシュテーブルにはクラスのメモリアドレスがマッピングされています(これは後述します).これもcategoryがインスタンス変数を追加できないのに、属性を追加できる理由であり、各属性システムが自動的に対応するインスタンス変数を生成する理由です.インスタンス変数は直接アクセスすることもselfポインタでアクセスすることもでき、属性は点構文のみで、Object-Cでは点構文は関数メソッドの呼び出しであり、例は以下の通りである.
@interface ClassB ()
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *address;
@end
@implementation ClassB {
    NSString *des;
}
 - (instancetype)init {
    self = [super init];
    if (self) {
        self.name = @"jashion";  //  "="      setter  
        NSString *temp = self.name;  //  "="      getter  
        NSLog(@"studentName: %@", self.name);
        des = @"Jashion's school";  //    
        self -> des = @"Bill's school";  //  self    
    }
    return self;
}

各プロパティ・システムはデフォルトでgetter関数とsetter関数を生成します.もちろん、怠惰なロードなどの関数を書き換えることができます.
@interface ClassA ()
@property (nonatomic, strong) NSMutableArray *array;
@end

@implementation ClassA
- (NSMutableArray *)array {
    if (!_array) {
        _array = [[NSMutableArray alloc] initWithCapacity: 0];
    }
    return _array;
}
@end

3.@synthesizeと@dynamic@synthesizeはgetterメソッドとsetterメソッドを合成するために使用され、最初はこのように書く必要があります.
@interface ClassB : NSObject {
    NSString *name;
}
@property (nonatomic, strong) NSString *name;
@end
@synthesize name;    
//      getter setter  ,         name    ,   @synthesize name = name
//      _name    ,   @synthesize name = _name

その後、システムはインスタンス変数を自動的に合成することができ、使用者が書く必要はありません.
@interface ClassB : NSObject 
@property (nonatomic, strong) NSString *name;
@end
@synthesize name = _name;    //  _name    

その後、コンパイラは@synthesizeの一歩も節約できると思っていたので、もっと簡潔になりました.
@interface ClassB : NSObject 
@property (nonatomic, strong) NSString *name;
@end
//    _name     gettter,setter  
@dynamicは、@synthesizeとは逆に、setterメソッドとgetterメソッドをカスタマイズして使用するより多くの自由を与えます.例を挙げます.
@interface ClassB : NSObject
@property (nonatomic, strong, readonly) NSString *name;
@end
@dynamic name;
 - (NSString *)name {
    return @"jashion";
}

ここで注意したいのは、propertyがreadonly修飾の場合、getter関数をカスタマイズする必要があり、readwriteの場合、getter関数とsetter関数をカスタマイズする必要があるということです.注意しなければならないのは、この時点でシステムが合成してくれないことです.nameインスタンス変数は、自分で生成する必要があります. 1. @synthesize @dynamic @synthesize object=_object。 2. @synthesize @dynamic, readwrite , setter getter, @dynamic, readonly , getter @dynamic, 。 3. @synthesize @dynamic, readwrite , setter getter , @synthesize, , 。 4.@dynamic , @dynamic, , , 。 5.@dynamic , , , 。
まとめ
属性とメンバー変数の最大の違いは、属性にgetterメソッドとsetterメソッドがあるため、ポイント構文を使用してアクセスできます.メンバー変数は使用できません.直接アクセスするか、self->アクセスを使用します.