在對象內部讀取數據時,應該直接經過實例變量來讀,而寫入數據時,則應經過屬性來寫。atom
_name = @"Jack"
不通過setter的消息發送,直接爲變量賦值,速度快。@property (nonatomic, copy) NSString *name;
_name = @"Jack"
; ,經過 self.name = @"Jack"
其實等同於_name = @"Jack".copy
。self.name = @"Jack"
會觸發KVO,_name = @"Jack"
不會self.name = @"Jack"
能夠在 setter 方法中進行斷點調試,每次賦值你都知道。NSString *str = _name
,賦值用 self.name = @"Jack"
。在對象內部訪問實例變量時,是經過屬性(self.proper
)來訪問仍是經過_proper
來訪問區別在因而否執行屬性的setter
、getter
方法。調試
若是執行屬性的setter
、getter
方法,則經過_proper
來訪問。rest
setter
、getter
方法,則經過屬性(self.proper
)來訪問。@interface Wrestler : NSObject @property (copy, nonatomic) NSString *name; // 將name聲明爲屬性 - (void)smell; @end @implementation Wrestler @synthesize name = _name; // 屬性name能夠使用實例變量_name直接訪問 - (void)setName:(NSString *)aName { NSLog(@"Set name"); _name = [aName copy]; } - (NSString *)name { NSLog(@"Get name"); return [_name copy]; } - (void)smell { NSLog(@"*** Smelling ***"); // 使用dot syntax訪問實例變量 NSLog(@"%@", self.name); // 直接調用屬性的getter方法 NSLog(@"%@", [self name]);
在初始化方法及dealloc
方法中,老是應該直接經過實例變量來讀寫數據。code
子類可能複寫setter
方法,用 self.proper = @""
可能不等同於_proper = @"".copy
。orm
Wrestler
的子類Cena
,該類繼承了屬性name
並重寫了其setter
方法,該方法會先檢驗名字後綴是否爲Cena
,不然拋出異常。@interface Cena : Wrestler - (instancetype)initWithName:(NSString *)aName; - (void)wrestle; @end @implementation Cena @synthesize name = _name; - (instancetype)initWithName:(NSString *)aName { self = [super init]; if (self) { NSLog(@"self.name = aName"); self.name = aName; } return self; } - (void)wrestle { NSLog(@"I'm %@, U can't see me", self.name); } - (void)setName:(NSString *)aName { if (![aName hasSuffix:@"Cena"]) { [NSException raise:NSInvalidArgumentException format:@"last name must be Cena"]; } _name = [aName copy]; } @end
(instancetype)init { self = [super init]; if (self) { NSLog(@"self.name = empty string"); self.name = @""; } return self;
Cena *cena = [[Cena alloc] initWithName:@"John Cena"]; [cena wrestle];
self.name = @"";
。調用子類中覆寫的name
的setter
方法,空白字符串明顯沒有@"Cena"
後綴,從而拋出異常。使用Lazy Initialization
配置的數據,應該經過屬性來讀取數據。對象
@property (strong, nonatomic) NSNumber *chamCount; - (NSNumber *)chamCount { if (!_chamCount) { _chamCount = @13; } return _chamCount;
不要在setter/getter方法中調用setter/getter
方法繼承
- (void)setName:(NSString *)aName { NSLog(@"Set name"); // _name = [aName copy]; self.name = aName; }
Set name
,崩潰。setter
方法中調用setter方法會不斷嵌套調用,最終致使程序崩潰。getter方法同理。在對象內部讀取數據時,應該直接經過實例變量來讀,而寫入數據時,則應經過屬性來寫。字符串
在初始化方法及dealloc方法中,老是應該直接經過實例變量來讀寫數據。get
使用Lazy Initialization配置的數據,應該經過屬性來讀取數據。string
不要在setter/getter方法中調用setter/getter方法。