屬性@property探索

  1. @property用來定義變量的屬性,定義的變量會(huì)自動(dòng)聲明變量,自動(dòng)生成setter方法和getter方法,便于變量的操作,常用的修飾詞是nonatomic,strong,readwrite等。

  2. 通過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;
  1. nonatomic是非原子性,修飾的變量不會(huì)對(duì)setter方法加鎖,屬于非線程安全,但是運(yùn)行速度快,適合用于移動(dòng)設(shè)備上;
    atomic是原子性,對(duì)setter方法加鎖,具有線程安全,但是會(huì)消耗大量資源
    系統(tǒng)默認(rèn)修飾是atomic,所以在聲明變量時(shí)需要指定nonatomic

  2. assign修飾整形變量
    strong是強(qiáng)引用
    copy是復(fù)制屬性
    weak是弱引用,避免循環(huán)引用會(huì)使用weak

  3. readwrite是可讀可寫,自動(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è)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容