OC語言之屬性關鍵字

屬性關鍵字

讀寫權限

  • readonly
  • readwrite(默認)

原子性

OC中的屬性可以修飾成nonatomic和atomic缔杉,即原子和非原子屬性久窟。atomic屬性設計的出發(fā)點是保證多線程下使用屬性的安全性妈拌,

  • atomic(默認)

atomic修飾的屬性可以保證賦值和獲取值(對成員屬性的直接獲取和賦值著蛙,并不代表操作和訪問),線程安全概荷。

假如一個atomic修飾的的數(shù)組,對數(shù)組進行賦值和獲取可以保證線程安全工闺,如果對數(shù)組進行操作乍赫,比如給數(shù)組添加對象或移除對象元素瓣蛀,則不在atomic的負責范圍內(nèi),沒辦法保證數(shù)組的線程安全雷厂。

使用atomic修飾的屬性并不會線程安全

源碼objc4-750.1

void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset)
{
    reallySetProperty(self, _cmd, newValue, offset, true, false, false);
}
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);
}

從使用PropertyLocks數(shù)組中的一個給寫操作上鎖惋增,在賦完值之后進行解鎖操作。

也就是說改鲫,atomic只是在 setter方法 中加鎖诈皿,當多個線程同時寫操作時,要進行排隊像棘。A線程對屬性進行寫操作稽亏,B線程不可以對該屬性進行寫操作,只有等A線程訪問結束缕题,B線程才能操作截歉。問題在于,當A線程再想對屬性進行讀操作烟零,讀取的是B線程寫的數(shù)據(jù)瘪松,這就破壞了線程安全,。如果再有C線程在A線程讀操作前Release這個屬性锨阿,那么程序就會Crash.
綜上宵睦,atomic 操作是原子性的,它只保證了屬性的setter和getter時的線程安全墅诡,并不能保證屬性線程安全壳嚎,atomic的使用只是更好的降低了線程出錯的可能性。

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);
}
  • nonatomic

atomic 與 nonatomic 的區(qū)別如下:

  1. atomicnonatomic的本質區(qū)別其實也就是在setter方法上的操作不同,atomic保證了gettersetter存取方法的線程安全末早,兩者都不能保證整個對象是線程安全的烟馅。
  2. nonatomic的速度要比atomic的快。

鑒于以上兩點荐吉,大部分使用的是nonatomic這個屬性焙糟。

那么問題來了,Apple為什么只給setter和getter方法加鎖而不直接使用@synchronized加鎖呢样屠?

看看 synchronized 操作的源碼穿撮, 簡單的一個注解,其實做了許多事情痪欲,每個@synchronized()代碼塊悦穿,使用了 objc_sync_enterobjc_sync_exitid2data三個加解鎖序列业踢,而這種作法相比使用一個atomic來修飾栗柒,只給settergetter方法加鎖的方式 在性能上要慢很多。讀寫操作一個屬性時瞬沦,通常需要很快來完成太伊,atomic的方式要適合這項工作。

在必要時逛钻,可以使用@synchronized僚焦,但是在保證多線程操作在發(fā)生錯誤的時候,不會發(fā)生dead lock曙痘。

引用計數(shù)

retain/strong(修飾對象的)

assign/unsafe_unretained(基本數(shù)據(jù)類型或對象)

assign與weak的區(qū)別有哪些芳悲?

  • assign修飾基本數(shù)據(jù)類型,如int,BOOL

  • assign修飾對象類型時边坤,不改變其引用計數(shù)名扛。

  • 會產(chǎn)生懸垂指針。

    assign修飾的對象在被釋放之后茧痒,其assign指針仍然指向原對象內(nèi)存地址肮韧,這個時候如果通過assign指針繼續(xù)訪問對象,可能會由于懸垂指針的原因導致內(nèi)存泄漏文黎,或程序異常惹苗。

  • weak不改變被修飾對象的引用計數(shù)

  • 所指對象在被釋放之后會自動置為nil

  • weak之修飾對象

copy

copy關鍵字.png
  • 可變對象的copymutableCopy都是深拷貝殿较。
  • 不可變對象的copy是淺拷貝耸峭,mutableCopy是深拷貝。
  • copy方法返回的都是不可變對象淋纲;

深拷貝與淺拷貝

淺拷貝就是對內(nèi)存地址的復制劳闹,讓目標對象指針和源對象指向同一片內(nèi)存空間。

  1. 會增加對象的引用計數(shù)
  2. 沒有發(fā)生新的內(nèi)存分配洽瞬。

深拷貝讓目標對象指針和源對象指針指向兩片內(nèi)容相同的內(nèi)存空間本涕。

  1. 不會增加對象的引用計數(shù)
  2. 產(chǎn)生了新的內(nèi)存空間分配
@property(copy) NSMutableArray *array;

如果像上面那樣聲明一個成員屬性會導致什么問題?

  1. 如果賦值過來的是NSMutableArray,copy之后是NSArray伙窃。

  2. 如果賦值過來的是NSArray,copy之后是NSArray菩颖。

    所以無論被賦值過來的是NSMutableArray,還是NSArray copy的結果都是不可變對象,由于原來的屬性被聲明為

    NSMutablArray就不可避免的有調用方調用其進行元素的添加與移除为障,此時由于copy的結果是NSArray晦闰,調用其子類方法的添加與移除會造成程序的崩潰。

OC語言筆試題

MRC下如何重寫retain修飾變量的setter方法?

@property(nonatomic, retain) id obj;
- (void)setObj:(id)obj
{
  if(_obj != obj) { //防止提早釋放了對象
    [_obj release];
    _obj = [obj retain];
  }
}

請簡述分類實現(xiàn)原理鳍怨?

KVO的實現(xiàn)原理是怎樣的呻右?

能否為分類添加成員變量?

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鞋喇,一起剝皮案震驚了整個濱河市声滥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌侦香,老刑警劉巖落塑,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纽疟,死亡現(xiàn)場離奇詭異,居然都是意外死亡憾赁,警方通過查閱死者的電腦和手機仰挣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缠沈,“玉大人膘壶,你說我怎么就攤上這事≈薹撸” “怎么了颓芭?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柬赐。 經(jīng)常有香客問我亡问,道長,這世上最難降的妖魔是什么肛宋? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任州藕,我火速辦了婚禮,結果婚禮上酝陈,老公的妹妹穿的比我還像新娘床玻。我一直安慰自己,他們只是感情好沉帮,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布锈死。 她就那樣靜靜地躺著,像睡著了一般穆壕。 火紅的嫁衣襯著肌膚如雪待牵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天喇勋,我揣著相機與錄音缨该,去河邊找鬼。 笑死川背,一個胖子當著我的面吹牛贰拿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渗常,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼壮不,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了皱碘?” 一聲冷哼從身側響起询一,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后健蕊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菱阵,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年缩功,在試婚紗的時候發(fā)現(xiàn)自己被綠了晴及。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫡锌,死狀恐怖虑稼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情势木,我是刑警寧澤蛛倦,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站啦桌,受9級特大地震影響溯壶,放射性物質發(fā)生泄漏。R本人自食惡果不足惜甫男,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一且改、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧板驳,春花似錦又跛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至直砂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浩习,已是汗流浹背静暂。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谱秽,地道東北人洽蛀。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像疟赊,于是被迫代替她去往敵國和親郊供。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,111評論 1 32
  • 307近哟、setValue:forKey和setObject:forKey的區(qū)別是什么驮审? 答:1, setObjec...
    AlanGe閱讀 1,554評論 0 1
  • 1.設計模式是什么疯淫? 你知道哪些設計模式地来,并簡要敘述?設計模式是一種編碼經(jīng)驗熙掺,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,165評論 0 12
  • 已經(jīng)回到湛江 最重要的事情還沒完成 計劃 目標 今天還是沒能未斑, 靜下心來, 去做一些事币绩。 工作上不要急 做好提前量...
    魔山樂水閱讀 31評論 0 0
  • 以下提示為了大家便于查找日課蜡秽,如果有更好的建議希望大家分享。謝謝缆镣! 快速找到今日日課 快速瀏覽日課 快速查詢?nèi)照n遞...
    周洋_圖樂園閱讀 180評論 0 0