OC的十萬個為什么--持續(xù)更新

OC的十萬個為什么

為什么atomic 無法保證線程安全

Atomic 只能保證單步操作的原子性位隶。因此帜讲,對于簡單的賦值或者讀取操作,atomic還是可以保證該操作的完整性涝缝。但是台囱,一旦涉及到多步驟操作淡溯,還是需要lock等其他的同步機制來確保線程安全。
實例: @peroperty(atomic, strong) NSMutableArray * array;
array = [NSMutableArray array]; //線程安全
[array addObject:dummyObject];//線程不安全玄坦,
在讀取array后血筑,執(zhí)行addObject 的過程中绘沉,array所指向的object 可能已經(jīng)在其他地方被釋放了.
而在實際應(yīng)用中煎楣,大部分操作都是多步驟操作,atomic可以在一定程度上減少crash的幾率车伞,從而掩蓋多線程問題择懂,但是卻無法從根本上解決線程安全問題。

使用 atomic 一定是線程安全的嗎?

答案很明顯另玖。不是,atomic 的本意是指屬性的存取方法是線程安全的,并不保證整個對象是線程安全的困曙。
聲明一個 NSMutableArray 的原子屬性 stuff,此時 self.stuff 和 self.stuff =othersulf 都是線程安全的表伦。但是,使用[self.stuff objectAtIndex:index]就不是線程安全的,需要用互斥鎖來保證線程安全性。

為什么說@sychronized(self)的性能差

@sychronized 所包含的代碼片段 一次只允許一個線程執(zhí)行慷丽,同時又會阻塞調(diào)用線程蹦哼, 類似上述表格中Serial queue + dispatch sync 的組合 。一旦這些代碼片段同時被多個線程訪問要糊,就會對性能造成較大的影響

為什么dispatch_sync在主線程會死鎖

sync會阻塞當(dāng)前的提交線程纲熏。
原因是:在串行隊列中,第二個同步線程要執(zhí)行锄俄,必須等待第一個同步線程執(zhí)行完成后才可進行局劲,但是第一個同步線程要執(zhí)行完又得等待第二個同步線程執(zhí)行完,因為第二個同步線程嵌套在第一個同步線程里奶赠,這就造成了兩個同步線程互相等待鱼填,即死鎖。
特別強調(diào):是在串行隊列里毅戈!
為什么dispatch_sync在主線程會死鎖
關(guān)于dispatch_sync死鎖問題
所以苹丸,對于
dispatch_sync(queue, ^{});
這行代碼的意義可以概括為: 會阻塞當(dāng)前線程等待串行queue中的所有任務(wù)執(zhí)行完成后再向下執(zhí)行。

為什么NSString苇经、NSDictionary谈跛、NSArray要使用copy修飾符呢?

NSString塑陵、NSArray感憾、NSDictionary等經(jīng)常使用copy關(guān)鍵字,是因為他們有對應(yīng)的可變類型:NSMutableString令花、NSMutableArray阻桅、NSMutableDictionary 它們之間可能進行賦值操作,為確保對象中的字符串值不會無意間變動兼都,應(yīng)該在設(shè)置新屬性時拷貝一份嫂沉。

總結(jié):對于非集合類對象的copy操作如下:
[immutableObject copy]; //淺復(fù)制
[immutableObject mutableCopy]; //深復(fù)制
[mutableObject copy]; //深復(fù)制
[mutableObject mutableCopy]; //深復(fù)制

采用同樣的方法可以驗證集合類對象的copy操作如下:
[immutableObject copy]; //淺復(fù)制
[immutableObject mutableCopy]; //單層深復(fù)制
[mutableObject copy]; //深復(fù)制
[mutableObject mutableCopy]; //深復(fù)制

*這個寫法會出什么問題: @property(copy)NSMutableArray array;

因為 copy 策略拷貝出來的是一個不可變對象,然而卻把它當(dāng)成可變對象使用,很容易造成程序奔潰這里還有一個問題,該屬性使用了同步鎖,會在創(chuàng)建時生成一些額外的代碼用于幫助編寫多線程程序,這會帶來性能問題,通過聲明 nonatomic 可以節(jié)省這些雖然
很小但是不必要額外開銷,在 iOS 開發(fā)中應(yīng)該使用 nonatomic 替代 atomic.

objc中向一個nil對象發(fā)送消息將會發(fā)生什么民鼓?

在 Objective-C 中向 nil 發(fā)送消息是完全有效的——只是在運行時不會有任何作用:
SomeClass * someObject;
someObject = nil;
[someObject doSomething];
objc在向一個對象發(fā)送消息時庙曙,runtime庫會根據(jù)對象的isa指針找到該對象實際所屬的類,然后在該類中的方法列表以及其父類方法列表中尋找方法運行玫芦,然后在發(fā)送消息的時候慎王,objc_msgSend方法不會返回值蚓土,所謂的返回內(nèi)容都是具體調(diào)用時執(zhí)行的。那么赖淤,回到本題蜀漆,如果向一個nil對象發(fā)送消息,首先在尋找對象的isa指針時就是0地址返回了咱旱,所以不會出現(xiàn)任何錯誤确丢。

比較讓你混淆的是绷耍,僵尸對象。僵尸對象并不是nil鲜侥,僵尸對象是你的object被銷毀或者用于其他地方了褂始,但是指向它的指針還在。會發(fā)生向一個object發(fā)送一個它沒有的方法描函。

__block和__weak修飾符的區(qū)別

因此病袄,__block和__weak修飾符的區(qū)別其實是挺明顯的:
1.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象赘阀,還可以修飾基本數(shù)據(jù)類型益缠。
2.__weak只能在ARC模式下使用,也只能修飾對象(NSString)基公,不能修飾基本數(shù)據(jù)類型(int)幅慌。
3.__block對象可以在block中被重新賦值,__weak不可以轰豆。
4.__block對象在ARC下可能會導(dǎo)致循環(huán)引用胰伍,非ARC下會避免循環(huán)引用,__weak只在ARC下使用酸休,可以避免循環(huán)引用骂租。

更多關(guān)于__block變量的詳細(xì)解釋,參見我的另一篇文章斑司,詳細(xì)探討了__block的實現(xiàn)原理

PS:__unsafe_unretained修飾符可以被視為iOS SDK 4.3以前版本的__weak的替代品渗饮,不過不會被自動置空為nil。所以盡可能不要使用這個修飾符宿刮。

__block
不用 __block, Block會捕獲棧上的變量(或指針)互站,將其復(fù)制為自己私有的const(變量), 捕獲他們的瞬時值。如果一個 block引用了一個棧變量或指針僵缺,那么這個block初始化的時候會擁有這個變量或指針的const副本胡桃,所以(被捕獲之后再在棧中改變這個變量或指針的值)是不起作用的);
__block修飾符所起到的作用就是只要觀察到該變量被block所持有磕潮,就將該變量在棧中的內(nèi)存地址放到堆中翠胰。

new和alloc/init的區(qū)別

概括來說,new和alloc/init在功能上幾乎是一致的自脯,分配內(nèi)存并完成初始化之景。
差別在于,采用new的方式只能采用默認(rèn)的init方法完成初始化冤今,
采用alloc的方式可以用其他定制的初始化方法闺兢。

alloc茂缚、init你弄懂50%了嗎戏罢?

MyClass *myObj = [MyClass alloc];
就是說alloc分配了一坨 內(nèi)存給對象屋谭,讓它不釋放,并且把地址返回給指針龟糕。那么這樣過后myobj為什么不能被使用呢桐磁?這是因為這片內(nèi)存還沒有被正確的初始化。
先看看 alloc 的API描述解說

  • (id)alloc
    Returns a new instance of the receiving class.

返回這個接受消息的類的一個實例.
The isa instance variable of the new instance is initialized to a data structure that describes the class; memory for all other instance variables is set to 0.

這個實例初始化后可以用來表示這個類的數(shù)據(jù)相關(guān)的結(jié)構(gòu);所有其他的實例變量的值都被設(shè)置成 0.
You must use an init... method to complete the initialization process. For example:

你必須使用 init... 方法來最終完成這個初始化的步驟,如下:
TheClass *newObject = [[TheClass alloc] init];
Do not override alloc to include initialization code. Instead, implement class-specific versions of init... methods.

不要重寫 alloc 來包含初始化的代碼.你可以使用指定版本的 init... 方法來達(dá)到你的目的.
For historical reasons, alloc invokes allocWithZone:.

由于歷史原因,allc 方法調(diào)用了 allocWithZone: 方法.

結(jié)論:

  1. alloc 后只是在系統(tǒng)中分配了內(nèi)存,這段內(nèi)存空間的大小與這個類本身結(jié)構(gòu)所占字節(jié)的大小相等,并返回了這段內(nèi)存的指針.
  1. alloc 將申請內(nèi)存空間中的值都設(shè)置為 0.
  2. alloc 調(diào)用了方法 allocWithZone:.
  3. alloc 就執(zhí)行了一次,沒有繼承的關(guān)系.

結(jié)論:

  1. 重寫 init 方法時需要先初始化父類的 init 方法.
  2. NSObject 中的 init 方法什么也沒做,只是返回了自己而已.
  3. 如果初始化失敗,會返回 nil.

<font color=#FF7F50 size=4>我的一些看法</font>

  1. OC僅僅支持單繼承,所以 init 方法是從繼承樹的頂部 NSObject 開始執(zhí)行的,每個鏈路中的對象都會執(zhí)行一次 init 操作,所以, init 操作會執(zhí)行多次,至上而下.
  1. alloc 就只執(zhí)行一次.
  2. 這些雖然看似簡單基礎(chǔ),但對于如何去中等程度的封裝一個類是很有用的,因為有時候,你覺得你懂了,可是你在封裝一個面向?qū)ο蟮囊粋€類的時候,莫名其妙的崩潰,你就傻眼了,因為我遇到過才會寫出來.
  3. 封裝分為多種,初級封裝以及中等程度的封裝,初級封裝會暴露出被你封裝的相關(guān)類的信息,比如返回值,入?yún)⑹裁吹?屬于初級階段.

_block和__weak的區(qū)別

__weak 和 __block 關(guān)鍵字的區(qū)別
__weak與__block區(qū)別讲岁,深層理解兩者區(qū)別

1我擂,在MRC 時代,__block 修飾可以避免循環(huán)引用缓艳;ARC時代校摩,__block 修飾,同樣會引起循環(huán)引用問題阶淘;
2衙吩,__block不管是ARC還是MRC模式下都可以使用,可以修飾對象溪窒,還可以修飾基本數(shù)據(jù)類型坤塞;
3,__weak只能在ARC模式下使用澈蚌,也只能修飾對象摹芙,不能修飾基本數(shù)據(jù)類型;
4宛瞄,__block對象可以在block中被重新賦值浮禾,__weak不可以;
5份汗,__unsafe_unretained修飾符可以被視為iOS SDK 4.3以前版本的__weak的替代品伐厌,不過不會被自動置空為nil。所以盡可能不要使用這個修飾符裸影。(__weak 會自動置為nil)

對象回收時Weak指針自動被置為nil的實現(xiàn)原理
__weak如何實現(xiàn)對象值自動設(shè)置為nil的

copy和mutableCopy

談?wù)刬OS中可變對象與不可變對象那些事兒

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挣轨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子轩猩,更是在濱河造成了極大的恐慌卷扮,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件均践,死亡現(xiàn)場離奇詭異晤锹,居然都是意外死亡,警方通過查閱死者的電腦和手機彤委,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門鞭铆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事车遂》舛希” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵舶担,是天一觀的道長坡疼。 經(jīng)常有香客問我,道長衣陶,這世上最難降的妖魔是什么柄瑰? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮剪况,結(jié)果婚禮上教沾,老公的妹妹穿的比我還像新娘。我一直安慰自己译断,他們只是感情好详囤,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著镐作,像睡著了一般藏姐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上该贾,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天羔杨,我揣著相機與錄音,去河邊找鬼杨蛋。 笑死兜材,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逞力。 我是一名探鬼主播曙寡,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼寇荧!你這毒婦竟也來了举庶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤揩抡,失蹤者是張志新(化名)和其女友劉穎户侥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峦嗤,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡蕊唐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了烁设。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片替梨。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出副瀑,到底是詐尸還是另有隱情弓熏,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布俗扇,位于F島的核電站硝烂,受9級特大地震影響箕别,放射性物質(zhì)發(fā)生泄漏铜幽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一串稀、第九天 我趴在偏房一處隱蔽的房頂上張望除抛。 院中可真熱鬧,春花似錦母截、人聲如沸到忽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喘漏。三九已至,卻和暖如春华烟,著一層夾襖步出監(jiān)牢的瞬間翩迈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工盔夜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留负饲,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓喂链,卻偏偏與公主長得像返十,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子椭微,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

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

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,125評論 29 470
  • 前一段時間爺爺住院洞坑,我一直在醫(yī)院照顧他。在醫(yī)院的那一段時間里蝇率,我越來越不想說話了检诗,不是煩躁,而是覺得每次說話都...
    輕浮女子閱讀 488評論 0 0
  • 3.Network networkcable between Host and Target. [root@Fri...
    Vvpl閱讀 579評論 1 0
  • 殺年豬“吃刨湯”的傳統(tǒng)習(xí)俗在我們樂山老家的鄉(xiāng)村里,是一種最淳樸间狂,最原汁原味攻泼,最和諧,最有人情味兒的習(xí)俗。盡管時代在...
    箜溪曉閱讀 1,102評論 0 4
  • 悵然若失忙菠,細(xì)細(xì)想來何鸡,本一無所有,失何物?而又得何物?迷之此牛欢,而后如撥云見日骡男,清澈洞明。 何謂得?而何謂失?得者傍睹,以...
    簡奕YJ閱讀 445評論 0 0