標籤:
記得剛學習OC時,對執行個體變數和屬性總是不太清楚。
比如下面代碼中在列印Person類對象的名字時,什麼時候用帶“_”的name,NSLog(@"%@",p1->_name);
什麼時候用不帶“_”的name,NSLog(@"%@",p1.name);
現在回想起來也是挺有意思的過往,寫下自己曾經的迷惘,紀念一下青春?。。。。
首先,使用執行個體變數編寫代碼。以及執行個體變數賦值要用到getter、setter方法。
@interface Person : NSObject{ @public NSString *_name; //定義執行個體變數_name}-(instancetype)initWithName:(NSString *)name; //初始化-(void)setName:(NSString *)name; //setter方法-(NSString *)name; //getter方法@end
@implementation Person //實現部分-(instancetype)initWithName:(NSString *)name{ if (self = [super init]) { _name = name; } return self;}-(void)setName:(NSString *)name{ _name = name;}-(NSString *)name{ return _name;}@end
int main(int argc, const char * argv[]) { //主函數 Person *p1 = [[Person alloc] initWithName:@"zhangsan"]; NSLog(@"%@",p1->_name); return 0;}
以上代碼,均使用的是執行個體變數。這個大家應該都明白。那麼什麼時候不用底線呢?
使用屬性編寫代碼(請比較兩者的代碼量)
首先明確兩點:
1、屬性的作用是產生setter以及getter方法的實現。並且如果.h檔案中未定義對應的執行個體變數時,系統會產生一個“_屬性名稱”的執行個體變數,但是產生的執行個體變數的可見度是私人的private。
2、OC中提供屬性的目的:為了簡化程式員的編碼。
@interface Person : NSObject@property(nonatomic,copy)NSString *name; -(instancetype)initWithName:(NSString *)name;@end@implementation Person-(instancetype)initWithName:(NSString *)name{ if (self = [super init]) { _name = name; } return self;}@endint main(int argc, const char * argv[]) { Person *p1 = [[Person alloc] initWithName:@"zhangsan"]; NSLog(@"%@",p1.name); //屬性是一對getter、getter方法,點文法是屬性的另一種調用格式。
return 0;}
此時列印,雖然屬性也產生了對應的執行個體變數,但是執行個體變數是私人的,所有並不能直接列印執行個體變數。用點文法,相當於調用了getter方法,傳回值依舊是執行個體變數儲存的值。
因為定義屬性時語義設定的關鍵字是copy。
setter內部實現
- (void)setGender:(NSString *)gender { if (_gender != gender) {
[_gender release];
_gender = [gender copy]; }
}
getter內部實現
- (NSString *)gender { return [[_gender retain] autorelease];
}
說到這裡,應該能夠理解屬性與執行個體變數的區別了。
Objective-C 執行個體變數與屬性的區別