在很久很久以前iOS是木有@property滴,我們必須自己定義實(shí)例變量和存取方法
@interface User : NSObject
{
NSString *name ;
NSInteger age;
}
@end
#import "User.h"
@interface User()
@end
@implementation User
-(void)setName:(NSString *)_name{
self->name = [_name copy];
}
-(NSString *)getName{
return self->name;
}
@end
屬性@property給我們帶來(lái)了什么?
@property = ivar + getter + setter; PS : 實(shí)例變量 = 成員變量 = ivar
@property 會(huì)根據(jù)(特質(zhì))的類型自定義合成不同的存取方法,這個(gè)過(guò)程由編譯 器在編譯期執(zhí)行。
編譯器還要自動(dòng)向類中添加適當(dāng)類型的實(shí)例變量,并且在屬性名前面加下劃線,以此作為實(shí)例變量的名字
屬性可以擁有的特質(zhì)分為四類:
原子性---nonatomic
讀/寫權(quán)限---readwrite(讀寫) readonly (只讀)
內(nèi)存管理語(yǔ)義---assign、strong、weak、unsafe_unretained、copy
方法名---getter=<name>、setter=<name>
@property (nonatomic, getter=isOn) BOOL on;
@synthesize
@synthesize 根據(jù)(特質(zhì))去添加存取方法 !
(如果沒(méi)有指定@synthesize , 會(huì)為屬性自動(dòng)添加 @synthesize propertyName = _propertyName)
_propertyName就是實(shí)例變量的名稱,propertyName是屬性名稱。
意味著使用屬性可以通過(guò)存取方法去訪問(wèn)_propertyName實(shí)例變量。
直接訪問(wèn)實(shí)例變量不會(huì)調(diào)用屬性的存取方法
@dynamic不會(huì)為屬性自動(dòng)創(chuàng)立合成方法,也不會(huì)自動(dòng)添加屬性。
#import <Foundation/Foundation.h>
@interface User : NSObject
@property (nonatomic,copy) NSString *subName;
@property (nonatomic,copy) NSString *name;
@end
#import "User.h"
@interface User()
@end
@implementation User
@synthesize subName = _subName;
@dynamic name ;
-(void)setName:(NSString *)name{
self.subName = [_subName stringByAppendingString:name];
}
@end
@dynamic 就是要告訴編譯器,代碼中用@dynamic修飾的屬性,其getter和setter方法會(huì)在程序運(yùn)行的時(shí)候或者用其他方式動(dòng)態(tài)綁定,以便讓編譯器通過(guò)編譯。其主要的作用就是用在NSManagerObject對(duì)象的屬性聲明上,由于此類對(duì)象的屬性一般是從Core Data的屬性中生成的,core data 框架會(huì)在程序運(yùn)行的時(shí)候?yàn)榇祟悓傩陨蒰etter和setter方法。
總結(jié)一下:
當(dāng)你想手動(dòng)管理 @property 的所有內(nèi)容時(shí),你就會(huì)嘗試通過(guò)實(shí)現(xiàn) @property 的所有“存取方法”(the accessor methods)或者使用 @dynamic 來(lái)達(dá)到這個(gè)目的,這時(shí)編譯器就會(huì)認(rèn)為你打算手動(dòng)管理 @property,于是編譯器就禁用了 autosynthesis(自動(dòng)合成)。
因?yàn)橛辛?autosynthesis(自動(dòng)合成),大部分開(kāi)發(fā)者已經(jīng)習(xí)慣不去手動(dòng)定義ivar,而是依賴于 autosynthesis(自動(dòng)合成),但是一旦你需要使用ivar,而 autosynthesis(自動(dòng)合成)又失效了,如果不去手動(dòng)定義ivar,那么你就得借助 @synthesize 來(lái)手動(dòng)合成 ivar。
當(dāng)你同時(shí)重寫了 setter 和 getter 時(shí),系統(tǒng)就不會(huì)生成 ivar(實(shí)例變量/成員變量)。這時(shí)候有兩種選擇:
手動(dòng)創(chuàng)建 ivar 或者使用@synthesize ; 關(guān)聯(lián) @property 與 ivar。
PS : effective Objective-C建議我們?cè)趯?duì)象內(nèi)部盡量直接訪問(wèn)實(shí)例變量而不是用存取方法。