屬性語義

  • @synthesize
@interface Test : NSObject 

@property (nonatomic, strong) NSString *name;

@end
  
@implementation Test
  
// 使用@synthesize必須先設(shè)置@property 
// @synthesize name == @synthesize name = name
// 會(huì)自動(dòng)生成setter getter方法聲明和實(shí)現(xiàn)(可以都重寫) 并且生成對(duì)應(yīng)的成員變量怜浅,成員變量名就是后面的名字
// 像下面這么寫的話,默認(rèn)的_name成員變量就變成了syn_name谢床,通過self.name或syn_name來訪問
// 如果遵循的協(xié)議內(nèi)部有property烦味,就要用@synthesize
@synthesize name = syn_name;

- (void)setName:(NSString *)name {
    syn_name = name;
}

- (NSString *)name {
    return syn_name;
}
@end
  • @dynamic
@interface Test : NSObject {
  NSInteger _dynamic_height
}

@property (nonatomic, assign) NSInteger height;

@end
  
@implementation Test
  
// 使用@dynamic必須先設(shè)置@property
// 告訴編譯器不要生成成員變量礁鲁,也不要生成setter箍铭,getter的實(shí)現(xiàn),但是setter getter的方法聲明還是有
// 如果直接調(diào)用test.height = x 會(huì)報(bào)方法找不到
// 一般會(huì)再寫一個(gè)成員變量蜜唾,然后實(shí)現(xiàn)setter getter方法 杂曲,如_dynamic_height 
// 不加成員變量也可以,實(shí)現(xiàn)方法就行
@dynamic height;

- (void)setHeight:(NSInteger)height {
    _dynamic_height = height;
}

- (NSInteger)height {
    return _dynamic_height;
}

@end
  • @property
@property (nonatomic, assign) NSInteger height;
// 等同于@synthesize height = _height; 屬性是用來描述成員變量在當(dāng)前類中的特征
  • nonatomic & atomic
// 源碼層面的區(qū)別
StripedMap<spinlock_t> PropertyLocks;
StripedMap<spinlock_t> StructLocks;
StripedMap<spinlock_t> CppObjectLocks;

#define MUTABLE_COPY 2

id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
    if (offset == 0) {
        return object_getClass(self);
    }

    // Retain release world
    id *slot = (id*) ((char*)self + offset);
    if (!atomic) return *slot;
        
    // Atomic retain release world
    spinlock_t& slotlock = PropertyLocks[slot];
    slotlock.lock();
    id value = objc_retain(*slot);
    slotlock.unlock();
    
    // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
    return objc_autoreleaseReturnValue(value);
}


static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) __attribute__((always_inline));

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
    if (offset == 0) {
        object_setClass(self, newValue);
        return;
    }

    id oldValue;
    id *slot = (id*) ((char*)self + offset);

    if (copy) {
        newValue = [newValue copyWithZone:nil];
    } else if (mutableCopy) {
        newValue = [newValue mutableCopyWithZone:nil];
    } else {
        if (*slot == newValue) return;
        newValue = objc_retain(newValue);
    }

    if (!atomic) {
        oldValue = *slot;
        *slot = newValue;
    } else {
        spinlock_t& slotlock = PropertyLocks[slot];
        slotlock.lock();
        oldValue = *slot;
        *slot = newValue;        
        slotlock.unlock();
    }

    objc_release(oldValue);
}

示例:

@interface Cat : NSObject
@property (nonatomic, copy) NSString *name;
@end

// 默認(rèn)cat.name = @"001"
@interface Person : NSObject
@property (nonatomic, strong) Cat *cat;
@end

1.threadA => 讀取cat.name
2.threadB => person.cat = Cat(@"002")
3.threadC => person.cat = Cat(@"003")

Q:threadA會(huì)讀取到什么值袁余?
Q:最后cat會(huì)是哪一個(gè)擎勘?

  • atomic:
    1.讀取到的值有三種可能: "001","002"颖榜,"003"
    2."002", "003"

  • nonatomic:
    1.讀取到的值可能是"001"棚饵,"002","003"或者報(bào)錯(cuò)掩完,why噪漾?
    2."002", "003"

set方法偽代碼:

- (void)setCat:(Cat *)cat {
    if (_cat != cat) {
        // 1
        [_cat release];
        // 2
        _cat = [cat retain];
        // 3
    }
}

在多線程環(huán)境中時(shí),如果threadA讀取值的時(shí)候且蓬,threadB剛好執(zhí)行到2欣硼,那么就有可能報(bào)錯(cuò)。

nonatomic atomic兩者最大的區(qū)別就是atomic在操作的時(shí)候加了一個(gè)自旋鎖恶阴,使得同一時(shí)間只有一個(gè)線程能訪問setter/getter诈胜。但是這只能保證setter getter操作是完整的(指操作要么完成豹障,要么失敗)焦匈,并且返回一個(gè)有效的值(即操作原子性)血公。
在很多時(shí)候,多線程競爭同一資源缓熟,僅靠atomic是遠(yuǎn)遠(yuǎn)不夠的累魔,所以會(huì)采用其他的措施,如加鎖荚虚,信號(hào)量薛夜,串行隊(duì)列等籍茧,iOS上資源比較寶貴版述,所以推薦使用nonatomic,MacOS上就隨意了寞冯。

  • 內(nèi)存管理關(guān)鍵字

strong:ARC時(shí)代用來取代retain渴析,默認(rèn)局部變量、成員變量都是strong 對(duì)象引用計(jì)數(shù)會(huì)+1吮龄,持有對(duì)象

weak:弱引用俭茧,不持有對(duì)象,不會(huì)增加對(duì)象的引用計(jì)數(shù)漓帚,當(dāng)指向的對(duì)象dealloc的時(shí)候會(huì)自動(dòng)置為nil母债,只能用于對(duì)象類型

assign:同weak,但是assign不會(huì)置空尝抖,可能會(huì)有野指針的存在毡们,且assign可用于基本類型如 int float NSInteger等,因?yàn)榛绢愋投际窃跅昧辽?臻g由系統(tǒng)來管理內(nèi)存衙熔,所以用assign

retain:持有對(duì)象 引用計(jì)數(shù)+1

copy:setter時(shí),對(duì)新值進(jìn)行copy搅荞,如果生成了新對(duì)象红氯,那么原來對(duì)象的引用計(jì)數(shù)不會(huì)變,沒有生成新對(duì)象咕痛,那被copy對(duì)象引用計(jì)數(shù)+1痢甘。對(duì)象要遵守NSCopying協(xié)議,較多用在NSArray NSString上

unsafe_unretained:有些類不支持weak修飾就用這個(gè)(可修飾基本數(shù)據(jù)類型)

  • 默認(rèn)值
@property NSString *name;
@property NSInteger age;

//等同于

@property (atomic, strong, readwrite) NSString *name;
@property (atomic, assign, readwrite) NSInteger age;

// 對(duì)象類型 就是strong 基本類型就是assign
  • 如果同時(shí)重寫setter和getter

編譯器會(huì)報(bào)錯(cuò)茉贡,它覺得你也不想要這個(gè)成員變量了产阱,加上@synthesize xxx 即可解決

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市块仆,隨后出現(xiàn)的幾起案子构蹬,更是在濱河造成了極大的恐慌王暗,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庄敛,死亡現(xiàn)場離奇詭異俗壹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)藻烤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門绷雏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怖亭,你說我怎么就攤上這事涎显。” “怎么了兴猩?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵期吓,是天一觀的道長。 經(jīng)常有香客問我倾芝,道長讨勤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任晨另,我火速辦了婚禮潭千,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘借尿。我一直安慰自己刨晴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布路翻。 她就那樣靜靜地躺著狈癞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帚桩。 梳的紋絲不亂的頭發(fā)上亿驾,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音账嚎,去河邊找鬼莫瞬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛郭蕉,可吹牛的內(nèi)容都是我干的疼邀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼召锈,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼旁振!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤拐袜,失蹤者是張志新(化名)和其女友劉穎吉嚣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹬铺,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尝哆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甜攀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秋泄。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖规阀,靈堂內(nèi)的尸體忽然破棺而出恒序,到底是詐尸還是另有隱情,我是刑警寧澤谁撼,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布歧胁,位于F島的核電站,受9級(jí)特大地震影響彤敛,放射性物質(zhì)發(fā)生泄漏与帆。R本人自食惡果不足惜了赌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一墨榄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧勿她,春花似錦袄秩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砍聊,卻和暖如春背稼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玻蝌。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蟹肘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俯树。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓帘腹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親许饿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阳欲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容