iOS 中定義屬性時的atomic灌灾、nonatomic、copy悲柱、assign锋喜、strong、weak幾個特性的區(qū)別

iOS編程中,定義屬性中的特性有atomic嘿般、nonatomic段标、copy、assign炉奴、strong逼庞、weak等,一般格式如下:

@property (nonatomic, strong) NSString *name; 

下面詳細解釋一下他們的區(qū)別盆佣。

atomic

  • 默認屬性往堡。
  • 當前進程進行到一半,其他線程來訪問當前線程共耍,可以保證先執(zhí)行完畢當前線程。
  • 只是保證setter/getter 完整吨瞎,不是線程安全痹兜。

例如:對于atomic的對象,線程A調(diào)用getter颤诀,同時線程B字旭、線程C都調(diào)用setter并設(shè)不同的值,最后線程A可能得到原來的值崖叫、也可能得到線程B遗淳、線程C設(shè)的值,只能夠保證得到的是原始值心傀、B線程設(shè)定的值屈暗、C線程設(shè)定的值三者中一個完整值,沒有辦法確定最終得到的是哪個值脂男。如果線程D調(diào)用release养叛,程序會崩潰。所以atomic只是read/write安全宰翅,不是thread安全弃甥。

Runtime objc-accessors.mm文件包含了屬性設(shè)值、取值源碼汁讼,如下所示:

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)
{
    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);
}

可以看到淆攻,atomic修飾的設(shè)值、取值方法使用了自旋鎖嘿架,確保線程同步瓶珊。

雖然設(shè)值、取值方法是原子操作眶明,但不代表是線程安全艰毒。例如,可變數(shù)組使用atomic修飾搜囱,只是取數(shù)組丑瞧、設(shè)置數(shù)組是原子操作柑土,但操作數(shù)組元素不再是線程安全。

nonatomic

  • 非默認屬性绊汹。
  • 兩個線程同時訪問同一個屬性將會導(dǎo)致無法預(yù)計的結(jié)果稽屏。
  • 優(yōu)點是程序運行速度快。

copy

  • 是owner西乖,不是reference(引用)狐榔。當對象可變時,可設(shè)置為copy获雕,用于獲取此時值的副本薄腻。
  • 新的對象引用計數(shù)為1,與原始對象引用計數(shù)無關(guān)届案,且原始對象引用計數(shù)不會改變庵楷。
  • 使用copy創(chuàng)建的新對象也是強引用,使用完成后需要負責釋放該對象楣颠。
  • copy特性可以減少對象對上下文的依賴尽纽。新對象、原始對象中任一對象的值改變不會影響另一對象的值童漩。
  • 要想設(shè)置該對象的特性為copy弄贿,該對象必須遵守NSCopying協(xié)議,F(xiàn)oundation類默認實現(xiàn)了NSCopying協(xié)議矫膨,所以只需要為自定義的類實現(xiàn)該協(xié)議即可差凹。更全面了解NSCopying協(xié)議,查看 深復(fù)制豆拨、淺復(fù)制直奋、copy、mutableCopy 一文施禾。

assign

  • 與copy相反脚线,只是reference,不是owner弥搞。只返回指針邮绿。
  • 用于float、int攀例、BOOL等類型船逮。
  • 釋放后再發(fā)送消息會導(dǎo)致程序崩潰。

strong

  • 默認屬性
  • strong = retain iOS引入ARC后粤铭,用strong替代了retain挖胃。
  • 創(chuàng)建一個強引用的指針,引用對象引用計數(shù)加1。
  • strong特性表示兩個對象內(nèi)存地址相同(建立一個指針酱鸭,進行指針拷貝)吗垮,內(nèi)容會一直保持相同,直到更改一方內(nèi)存地址凹髓,或?qū)⑵湓O(shè)置為nil烁登。
  • 如果有多個對象同時引用一個屬性,任一對象對該屬性的修改都會影響其他對象獲取的值蔚舀。
  • 所有實例變量饵沧、局部變量默認都是strong。

weak

  • 只是reference赌躺,不是owner狼牺。即引用計數(shù)不會加1。
  • 可將weak對象設(shè)為nil寿谴,向nil發(fā)送消息锁右,什么都不會執(zhí)行,程序也不會崩潰讶泰。
  • 代理使用weak。delegate幾乎一直own代理對象拂到,所以代理對象應(yīng)該對代理使用weak痪署,否則會形成循環(huán)引用(retain cycle)。但也有例外兄旬,如果代理對象的生命周期比代理短狼犯,代理對象也可以使用strong。
  • IBOutlet常用weak领铐。

關(guān)于strong和weak對比的一個形象例子

假設(shè)對象是一條小狗悯森,小狗想跑走(be deallocated)。

strong類型就像是拴狗的繩子绪撵,只要有一條繩子栓住狗瓢姻,它就不能跑走,如果有五條繩子拴著同一條狗(五個strong類型指向同一個對象)音诈,只有當五條繩子都釋放狗才可以跑走幻碱。

weak類型就像是小孩子看著小狗說:看這里有小狗。只要還有繩子拴著小狗细溅,小孩子們就可以繼續(xù)指著小狗說:看這里有小狗褥傍。當繩子釋放了的時候,不管有多少小孩子依舊在指著小狗說:看這里的小狗喇聊。小狗都會跑掉恍风。

當最后一個strong指針不再指向這個對象,這個對象就會被釋放,此時朋贬,所有指向這個對象的weak指針都將被清空凯楔。

readonly

  • 非默認屬性
  • 只有可讀方法,也就是只有g(shù)etter方法兄世。

readwrite

  • 默認屬性
  • 如果希望一個屬性只允許自己讀寫啼辣,而對所有外部文件都是只讀的,可以在接口部分聲明該屬性為readonly類型御滩,最后在私有接口部分重寫該屬性為readwrite類型鸥拧。

歡迎更多指正:https://github.com/pro648/tips/wiki

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市削解,隨后出現(xiàn)的幾起案子富弦,更是在濱河造成了極大的恐慌,老刑警劉巖氛驮,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腕柜,死亡現(xiàn)場離奇詭異,居然都是意外死亡矫废,警方通過查閱死者的電腦和手機盏缤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓖扑,“玉大人唉铜,你說我怎么就攤上這事÷筛埽” “怎么了潭流?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柜去。 經(jīng)常有香客問我灰嫉,道長,這世上最難降的妖魔是什么嗓奢? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任讼撒,我火速辦了婚禮,結(jié)果婚禮上蔓罚,老公的妹妹穿的比我還像新娘椿肩。我一直安慰自己,他們只是感情好豺谈,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布郑象。 她就那樣靜靜地躺著,像睡著了一般茬末。 火紅的嫁衣襯著肌膚如雪厂榛。 梳的紋絲不亂的頭發(fā)上盖矫,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音击奶,去河邊找鬼辈双。 笑死,一個胖子當著我的面吹牛柜砾,可吹牛的內(nèi)容都是我干的湃望。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼痰驱,長吁一口氣:“原來是場噩夢啊……” “哼证芭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起担映,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤废士,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蝇完,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體官硝,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年短蜕,在試婚紗的時候發(fā)現(xiàn)自己被綠了氢架。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡朋魔,死狀恐怖达箍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铺厨,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布硬纤,位于F島的核電站解滓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏筝家。R本人自食惡果不足惜洼裤,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望溪王。 院中可真熱鬧腮鞍,春花似錦、人聲如沸莹菱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽道伟。三九已至迹缀,卻和暖如春使碾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祝懂。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工票摇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砚蓬。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓矢门,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灰蛙。 傳聞我的和親對象是個殘疾皇子祟剔,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

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