iOS開發(fā) 快速進(jìn)階與實(shí)戰(zhàn)

iOS開發(fā) 快速進(jìn)階與實(shí)戰(zhàn)

類蛛淋、類屬性卖鲤、類方法疗认、黑魔法

  • 類屬性
    NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END: 這是系統(tǒng)提供的兩個(gè)宏,用來將默認(rèn)未標(biāo)明為nullable還是nonnull的類的屬性都默認(rèn)設(shè)置為nonnull突倍;目的是為了兼容Swift的可選值類型(可橋接成更明確的方法)队伟,我們希望在對(duì)應(yīng)的Property中加上特定的修飾符穴吹;但是如果一個(gè)類的屬性很多,這樣會(huì)比較麻煩嗜侮,所以系統(tǒng)引入了NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END港令。
  • 類的初始化
    通過UNAVAILABLE_ATTRIBUTE可以修飾在頭文件中禁用的其他初始化方法,保證只有自己提供的初始化方法才是唯一途徑锈颗。
    image.png
  • 類方法的self
    類方法的self指向的是當(dāng)前類顷霹,而不是固定的某個(gè)類,還可能是這個(gè)類的子類击吱。
  • 類屬性
    類可以看做是其原類的實(shí)例淋淀。在objc對(duì)象的結(jié)構(gòu)體,其中有一個(gè)methodLists覆醇,用于存儲(chǔ)對(duì)象方法的列表朵纷;根據(jù)OC的運(yùn)行時(shí)機(jī)制,一個(gè)類實(shí)例調(diào)用方法永脓,會(huì)在該類的方法表中檢索(methodLists)袍辞,如果未能找到則會(huì)沿著類關(guān)系繼承鏈路逐層向父類查找,也就是父類的methodLists常摧;如果都找不到搅吁,則會(huì)按照消息傳遞的邏輯進(jìn)行。同理,一個(gè)類的變量存在類的ivars中似芝,沒有則在父類中查找那婉。
    XCode8的發(fā)布,表示Swift進(jìn)入了3.0的時(shí)代党瓮,同時(shí)Objective-C也引入了類屬性详炬,用法是在property的修飾符中加入class,表示這是一個(gè)類屬性寞奸,并在實(shí)現(xiàn)中手動(dòng)實(shí)現(xiàn)getter呛谜、setting方法。
    image.png

    image.png

    很多類的屬性中枪萄,并不需要設(shè)置為實(shí)例屬性隐岛,因?yàn)槊總€(gè)實(shí)例都會(huì)創(chuàng)建一遍,開辟一塊內(nèi)存瓷翻。類屬性的使用類似于自己實(shí)現(xiàn)property聚凹。類屬性本身不提供存儲(chǔ),類似于Swift的計(jì)算屬性齐帚。
  • 黑魔法
    黑魔法就是OC語言中的runtime給類的類方法或者實(shí)例方法做交換妒牙,達(dá)到不用修改原類就能在特定的方法做操作。黑魔法的使用時(shí)AOP編程思想的重要實(shí)現(xiàn)对妄。交換方法雖然會(huì)給特定情況下的開發(fā)帶來便利湘今,但是也會(huì)帶來一些侵入性,可能會(huì)影響其他類的代碼剪菱,所以要謹(jǐn)慎使用摩瞎。

底層實(shí)現(xiàn)分析

  • 內(nèi)存分區(qū)

棧區(qū):由系統(tǒng)來自動(dòng)分配釋放,是一個(gè)棧的數(shù)據(jù)結(jié)構(gòu)孝常,存儲(chǔ)函數(shù)的參數(shù)旗们、局部變量、引用构灸;
堆區(qū):由開發(fā)者手動(dòng)管理或者程序結(jié)束后由系統(tǒng)全部回收蚪拦,是一種樹狀的數(shù)據(jù)結(jié)構(gòu),一般用于存儲(chǔ)由malloc冻押、new等方式創(chuàng)建的對(duì)象。開發(fā)中多數(shù)內(nèi)存管理問題多出于此盛嘿,未能及時(shí)回收內(nèi)存或者內(nèi)存溢出洛巢、內(nèi)存泄漏;
全局區(qū)(靜態(tài)存儲(chǔ)區(qū)):用于存放全局變量和靜態(tài)變量次兆,進(jìn)程結(jié)束后系統(tǒng)回收稿茉;
常量區(qū):主要存儲(chǔ)基本數(shù)據(jù)類型的值,以及常量,進(jìn)程結(jié)束后系統(tǒng)回收漓库;
代碼區(qū):存儲(chǔ)要執(zhí)行函數(shù)的二進(jìn)制代碼恃慧,如果需要執(zhí)行就加載到該區(qū)域中。

以下有幾個(gè)特例:

  1. 字符串類型:多個(gè)直接聲明的相同字符串在內(nèi)存中只占用一份內(nèi)存:
    image.png

因?yàn)橥粋€(gè)固定的字符串渺蒿,在編譯器就確定了痢士,不會(huì)更改。

  1. block類型
    block聲明的時(shí)候是在棧中存儲(chǔ)的茂装,但是賦值給變量的時(shí)候會(huì)復(fù)制到堆中怠蹂。
  • 初始化
    創(chuàng)建一個(gè)對(duì)象通過alloc和init兩步實(shí)現(xiàn),alloc是為該對(duì)象分配內(nèi)存空間少态,init才是真正的初始化城侧。
    在Objective-C中,初始化方法其實(shí)并不是安全的彼妻,因?yàn)閷?duì)初始化方法沒有限制嫌佑,開發(fā)者可以任意調(diào)用以及實(shí)現(xiàn)某個(gè)類的初始化方法。例如UITableView中 initWithFrame方法是初始化方法侨歉,但是沒有約束屋摇,會(huì)導(dǎo)致濫用,很可能直接使用init方法進(jìn)行初始化为肮。
    initWithFrame方法是一個(gè)NS_DESIGNATED_INITIALIZER方法摊册,表明該方法是一個(gè)Designated方法。
    Designated和Convenience初始化方法之間有什么關(guān)系呢颊艳?Designated方法是對(duì)外提供的標(biāo)準(zhǔn)的初始化方法茅特。如果該類還需要?jiǎng)?chuàng)建一些補(bǔ)充的初始化方法,需要在內(nèi)部調(diào)用當(dāng)前類的Designated方法棋枕。例如UITableView的init方法內(nèi)部調(diào)用了initWithFrame方法白修,這些補(bǔ)充的方法稱為Convenience初始化方法。

  • 拷貝

深拷貝:拷貝一個(gè)實(shí)例對(duì)象到一個(gè)新的內(nèi)存地址重斑;
淺拷貝:拷貝一個(gè)實(shí)例對(duì)象的指針兵睛;
完全深拷貝:對(duì)對(duì)象的每一層都是重新創(chuàng)建的實(shí)例變量,不存在指針拷貝窥浪;例如對(duì)數(shù)組的歸檔解檔就是完全深拷貝祖很;

  • 數(shù)組與集合
    不可變數(shù)組的存儲(chǔ)方式是一串連續(xù)的地址空間存儲(chǔ)的形式,對(duì)于可變數(shù)組是鏈表的形式漾脂;
    數(shù)組與鏈表的區(qū)別:數(shù)組查找更快假颇、鏈表增刪更快晓折;

  • 字典(Map)與哈希表
    字典中的鍵可以為任意實(shí)現(xiàn)NSCoping協(xié)議的對(duì)象倒淫,但是如果鍵不是NSString類型的話,不可以使用KVC進(jìn)行存取值缤弦。在OC中無論是鍵還是值都不能是nil,如果傳入一個(gè)nil形耗,會(huì)造成crash哥桥。
    字典的結(jié)構(gòu)和工作原理:
    在打印字典的時(shí)候會(huì)發(fā)現(xiàn)字典內(nèi)容的打印結(jié)果順序是不固定的,是因?yàn)樽值渲薪o一個(gè)很重要的概念:哈希表激涤。

  • KVC(Key-Value-Coding)
    KVC依賴于Runtime拟糕,在OC的動(dòng)態(tài)性方面發(fā)揮了重要作用。
    主要功能是直接通過變量名來訪問變量成員昔期,不管是私有還是公有已卸。

開發(fā)原理相關(guān)

  • 定時(shí)器的引用
    image.png

    這時(shí)我們在dealloc中對(duì)timer執(zhí)行invalidate方法,在頁面銷毀時(shí)該方法并不會(huì)被調(diào)用硼一,這時(shí)為什么呢累澡?
    事實(shí)上,timer會(huì)直接對(duì)傳遞過來的target強(qiáng)引用般贼,即使是weak修飾的愧哟。如果控制器本身對(duì)timer有強(qiáng)引用,那會(huì)造成循環(huán)運(yùn)用哼蛆。
    定時(shí)器的啟用還涉及到一個(gè)領(lǐng)域就是Runloop蕊梧,timer必須加到Runloop中才有效。在repeats為YES的情況下是通過Runloop來控制timer的腮介,而Runloop可以理解為一個(gè)處理事務(wù)的死循環(huán)肥矢,有時(shí)候處理事務(wù)可能會(huì)消耗一些事件導(dǎo)致某次循環(huán)時(shí)間稍微長了一些,因此會(huì)出現(xiàn)平常所說的timer不準(zhǔn)確的現(xiàn)象叠洗。所以Runloop是對(duì)timer有強(qiáng)引用的甘改。


    WeChat1558af0f86d29891e62a4d13eb4bbc6e.png

    當(dāng)前Runloop是不會(huì)被銷毀的,強(qiáng)引用了timer灭抑,而timer通過參數(shù)強(qiáng)引用了target十艾,也就是控制器self,所以不管self對(duì)timer是強(qiáng)引用還是弱引用腾节,都是不能打破這種循環(huán)引用的忘嫉。
    以上所說的timer問題是對(duì)于重復(fù)的定時(shí)器,不重復(fù)的定時(shí)器在僅執(zhí)行一次selector后就自動(dòng)invalidate了案腺。

    解決方案一:創(chuàng)建中間對(duì)象:弱引用原本timer應(yīng)持有的target庆冕;也就是讓控制器弱引用timer,打破循環(huán)引用劈榨;
    解決方案二:利用消息轉(zhuǎn)發(fā)機(jī)制來實(shí)現(xiàn):創(chuàng)建一個(gè)類愧杯,弱引用target,返回該類的實(shí)例鞋既,然后實(shí)現(xiàn)消息轉(zhuǎn)發(fā)機(jī)制力九,將傳遞給該實(shí)例的消息轉(zhuǎn)發(fā)給target。

  • 動(dòng)畫事務(wù)
    我們平時(shí)常用的動(dòng)畫有以下幾種:

  1. UIView的類方法:animateWithDuration
  2. CAAnimation
  3. POP:基于CADisplayLink
  4. 隱式動(dòng)畫:基于CALayer邑闺,CALayer是UIView的一個(gè)屬性跌前,負(fù)責(zé)顯示;而UIView主要負(fù)責(zé)用戶交互陡舅;上述三種直接對(duì)UIView進(jìn)行動(dòng)畫抵乓,實(shí)際也是通過CALayer來實(shí)現(xiàn)的;
  • 響應(yīng)鏈
    當(dāng)我們點(diǎn)擊屏幕時(shí)靶衍,系統(tǒng)會(huì)記錄該次的觸摸事件灾炭,添加到Application的事件隊(duì)列中,然后從keyWindow開始依次向上尋找颅眶,結(jié)合響應(yīng)者的pointInside方法和hitTest方法找到處理該觸摸時(shí)間的view蜈出,從而也形成了一條事件響應(yīng)鏈;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涛酗,一起剝皮案震驚了整個(gè)濱河市铡原,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌商叹,老刑警劉巖燕刻,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剖笙,居然都是意外死亡卵洗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門弥咪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來过蹂,“玉大人,你說我怎么就攤上這事酪夷×裥ィ” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵晚岭,是天一觀的道長鸥印。 經(jīng)常有香客問我,道長坦报,這世上最難降的妖魔是什么库说? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮片择,結(jié)果婚禮上潜的,老公的妹妹穿的比我還像新娘。我一直安慰自己字管,他們只是感情好啰挪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布信不。 她就那樣靜靜地躺著,像睡著了一般亡呵。 火紅的嫁衣襯著肌膚如雪抽活。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天锰什,我揣著相機(jī)與錄音下硕,去河邊找鬼。 笑死汁胆,一個(gè)胖子當(dāng)著我的面吹牛梭姓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嫩码,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼誉尖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谢谦?” 一聲冷哼從身側(cè)響起释牺,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎回挽,沒想到半個(gè)月后没咙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡千劈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年祭刚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墙牌。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涡驮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出喜滨,到底是詐尸還是另有隱情捉捅,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布虽风,位于F島的核電站棒口,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辜膝。R本人自食惡果不足惜无牵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厂抖。 院中可真熱鬧茎毁,春花似錦、人聲如沸忱辅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至橡卤,卻和暖如春夜只,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蒜魄。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留场躯,地道東北人谈为。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像踢关,于是被迫代替她去往敵國和親伞鲫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,101評(píng)論 1 32
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔签舞,今天18年5月份再次想寫文章秕脓,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,756評(píng)論 2 9
  • 前言 說是前言,其實(shí)也是本文誕生的目的儒搭。隨著公司業(yè)務(wù)的不斷增加吠架,功能的快速迭代,app的業(yè)務(wù)線越來越多搂鲫,代碼體積變...
    夢翔_d674閱讀 1,493評(píng)論 0 2
  • 面向?qū)ο蟮娜筇卣?并作簡單的介紹傍药。 面向?qū)ο蟮娜齻€(gè)基本特征是:封裝、繼承魂仍、多態(tài)拐辽。 1.封裝是面向?qū)ο蟮奶卣髦?...
    xiny123閱讀 1,432評(píng)論 0 6
  • 有人在讀過我談管理和職場經(jīng)驗(yàn)的文章后俱诸,留言,說:“讀你的文章赊舶,收獲了很多睁搭,非常感謝。真的很羨慕你锯岖,做了那么多的職位...
    古爾浪洼閱讀 1,002評(píng)論 7 13