@property用來定義變量的屬性,定義的變量會(huì)自動(dòng)聲明變量,自動(dòng)生成setter方法和getter方法,便于變量的操作,常用的修飾詞是nonatomic,strong,readwrite等。
通過clang的方法查看@property生成的變量和方法如下:
寫一個(gè)屬性
@interface Property ()
@property(nonatomic, copy) NSString * myName;
@end
執(zhí)行clang命令
clang -rewrite-objc Property.m
得到.cpp文件,其中變量和方法的部分如下
我們創(chuàng)建的類為MyProperty,MyProperty_IMPL為類的實(shí)現(xiàn),可以看到系統(tǒng)自動(dòng)生成的變量_myName
typedef struct objc_object MyProperty;
typedef struct {} _objc_exc_MyProperty;
#endif
extern "C" unsigned long OBJC_IVAR_$_MyProperty$_myName;
struct MyProperty_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *_myName;
};
static NSString * _I_MyProperty_myName(MyProperty * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_MyProperty$_myName)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);
static void _I_MyProperty_setMyName_(MyProperty * self, SEL _cmd, NSString *myName) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct MyProperty, _myName), (id)myName, 0, 1); }
將自動(dòng)生成的ivar和method加入列表
static struct /*_ivar_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count;
struct _ivar_t ivar_list[1];
} _OBJC_$_INSTANCE_VARIABLES_MyProperty __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_ivar_t),
1,
{{(unsigned long int *)&OBJC_IVAR_$_MyProperty$_myName, "_myName", "@\"NSString\"", 3, 8}}
};
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[4];
} _OBJC_$_INSTANCE_METHODS_MyProperty __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
4,
{{(struct objc_selector *)"myName", "@16@0:8", (void *)_I_MyProperty_myName},
{(struct objc_selector *)"setMyName:", "v24@0:8@16", (void *)_I_MyProperty_setMyName_},
{(struct objc_selector *)"myName", "@16@0:8", (void *)_I_MyProperty_myName},
{(struct objc_selector *)"setMyName:", "v24@0:8@16", (void *)_I_MyProperty_setMyName_}}
};
從.cpp文件可以看到,@property會(huì)在編譯階段自動(dòng)生成ivar成員變量"_myName"、getter方法"myName"和setter方法"setMyName:"
{
NSString *_myName;
}
- (void)setMyName:(NSString *)myName;
- (NSString *)myName;
nonatomic是非原子性,修飾的變量不會(huì)對(duì)setter方法加鎖,屬于非線程安全,但是運(yùn)行速度快,適合用于移動(dòng)設(shè)備上;
atomic是原子性,對(duì)setter方法加鎖,具有線程安全,但是會(huì)消耗大量資源
系統(tǒng)默認(rèn)修飾是atomic,所以在聲明變量時(shí)需要指定nonatomicassign修飾整形變量
strong是強(qiáng)引用
copy是復(fù)制屬性
weak是弱引用,避免循環(huán)引用會(huì)使用weakreadwrite是可讀可寫,自動(dòng)生成setter和getter方法
readonly為只讀狀態(tài),只會(huì)生成getter方法
調(diào)用屬性的setter方法會(huì)觸發(fā)鍵值觀測(cè)
_myName = "ella"; //該操作是賦值操作,不會(huì)觸發(fā)鍵值觀測(cè)
self.myName = "ella"; //該操作調(diào)用的是setter方法,會(huì)觸發(fā)鍵值觀測(cè)