iOS面試常見問題匯總

1幕庐、nil 、 NSNull

nil:針對對象骤素,而空對象不是說不占用空間匙睹,相當于一個“洗白”,回到初始狀態(tài)济竹。

我們給對象賦值時一般會使用object = nil痕檬,表示我想把這個對象釋放掉;或者對象由于某種原因送浊,經(jīng)過多次release梦谜,于是對象引用計數(shù)器為0了,系統(tǒng)將這塊內(nèi)存釋放掉袭景,這個時候這個對象為nil唁桩,我稱它為“空對象”。(注意:我這里強調(diào)的是“空對象”浴讯,下面我會拿它和“值為空的對象”作對比6湎摹!S芘Α)

所以對于這種空對象仰猖,所有關(guān)于retain的操作都會引起程序崩潰,例如字典添加鍵值或數(shù)組添加新原素等

NSNull:針對指針奈籽,對對象指針和非對象指針都有效饥侵,Null不會占用空間。

NSNull和nil的區(qū)別在于衣屏,nil是一個空對象躏升,已經(jīng)完全從內(nèi)存中消失了,而如果我們想表達“我們需要有這樣一個容器狼忱,但這個容器里什么也沒有”的觀念時膨疏,我們就用到NSNull一睁,我稱它為“值為空的對象”。如果你查閱開發(fā)文檔你會發(fā)現(xiàn)NSNull這個類是繼承NSObject佃却,并且只有一個“+ (NSNull *) null者吁;”類方法。這就說明NSNull對象擁有一個有效的內(nèi)存地址饲帅,所以在程序中對它的任何引用都是不會導致程序崩潰的复凳。

2、沙盒包有含三個目錄:Documents灶泵、Library育八、temp

????1)Documents :這個目錄用于存儲用戶數(shù)據(jù)。該路徑可通過配置實現(xiàn)iTunes共享文件赦邻。iTunes或iCloud會對其進行備份髓棋。

????2)Library :這個目錄下有兩個子目錄:

? ? ? ? ? ????????Preferences :包含應(yīng)用程序的偏好設(shè)置文件。iTunes或iCloud會對其進行備份深纲。

? ? ? ? ??????????Caches :存放緩存數(shù)據(jù)仲锄,可以重新下載或生成的數(shù)據(jù)劲妙,同時沒有這些數(shù)據(jù)不會影響用戶離線使用湃鹊。緩存數(shù)據(jù)在設(shè)備低存儲空間時可能被刪除。iTunes或iCloud不會對其進行備份镣奋。

?????3)tmp :這個目錄用于存放臨時文件币呵,保存應(yīng)用程序再次啟動過程中不需要的信息。系統(tǒng)會不定期刪除其中的文件侨颈。該路徑下的文件不會被iTunes備份余赢。

3、事件傳遞鏈

? ? ?先判斷點是否在View內(nèi)部哈垢,然后遍歷subViews

????- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;?

? ? ?判斷點是否在這個View內(nèi)部

????- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;?

? ? ? ?// default returns YES if point is in bounds

????A: 流程

????????1:先判斷該層級是否能夠響應(yīng)(1.alpha>0.01 2.userInteractionEnabled == YES 3.hidden = NO)

????????2:判斷改點是否在view內(nèi)部,

????????3:如果在那么遍歷子view繼續(xù)返回可響應(yīng)的view妻柒,直到?jīng)]有。

????B:常見問題

????????父view設(shè)置為不可點擊耘分,子view可以點擊嗎

????????不可以举塔,hit test 到父view就截止了

????????子view設(shè)置view不可點擊不影響父類點擊

????????同父view覆蓋不影響點擊

????????手勢對responder方法的影響

????C:實際用法

????????點一一個圓形控件,如何實現(xiàn)只點擊圓形區(qū)域有效

????????重載pointInside求泰。此時可將外部的點也判斷為內(nèi)部的點央渣,反之也可以

4、進程和線程

????????1)線程在進程下行進(單純的車廂無法運行)

????????2)一個進程可以包含多個線程(一輛火車可以有多個車廂)

????????3)不同進程間數(shù)據(jù)很難共享(一輛火車上的乘客很難換到另外一輛火車渴频,比如站點換乘)

????????4)同一進程下不同線程間數(shù)據(jù)很易共享(A車廂換到B車廂很容易)

????????5)進程要比線程消耗更多的計算機資源(采用多列火車相比多個車廂更耗資源)

????????6)進程間不會相互影響芽丹,一個線程掛掉將導致整個進程掛掉(一列火車不會影響到另外一列火車,但是如果一列火車上中間的一節(jié)車廂著火了卜朗,將影響到所有車廂)

????????7)進程可以拓展到多機拔第,進程最多適合多核(不同火車可以開在多個軌道上咕村,同一火車的車廂不能在行進的不同的軌道上)

????????8)進程使用的內(nèi)存地址可以上鎖,即一個線程使用某些共享內(nèi)存時蚊俺,其他線程必須等它結(jié)束培廓,才能使用這一塊內(nèi)存。(比如火車上的洗手間)-"互斥鎖"

????????9)進程使用的內(nèi)存地址可以限定使用量(比如火車上的餐廳春叫,最多只允許多少人進入肩钠,如果滿了需要在門口等,等有人出來了才能進去)-“信號量”

????GCD的隊列分為2大類型:

? ? ? ? ? 1暂殖、并發(fā)隊列

????????????????可以讓多個任務(wù)并發(fā)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù))

????????????????并發(fā)功能只有在異步函數(shù)下才有效

? ? ? ? ? 2价匠、串行隊列

????????????????任務(wù)一個接一個的執(zhí)行(一個任務(wù)執(zhí)行完畢后執(zhí)行下一個任務(wù))

? ??同步、異步呛每、并發(fā)踩窖、串行

????????????????同步和異步主要影響:能不能開啟新的線程

????????????????????????同步:在當前線程中執(zhí)行任務(wù),不具備開啟線程的能力

????????????????????????異步:在新的線程中執(zhí)行任務(wù)晨横,具備開啟新線程的能力

????????????????并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式

????????????????????????并發(fā):多個任務(wù)同時執(zhí)行

????????????????????????串行:一個任務(wù)執(zhí)行完畢后洋腮,在執(zhí)行下一個任務(wù)

5、objc_getClass與object_getClass

????1)Class objc_getClass(const char *aClassName)

????????????1> 傳入字符串類名

????????????2> 返回對應(yīng)的類對象

????2)Class object_getClass(id obj)

????????????1> 傳入的obj可能是instance對象手形、class對象啥供、meta-class對象

????????????2> 返回值

????????????????????a) 如果是instance對象,返回class對象

????????????????????b) 如果是class對象库糠,返回meta-class對象

????????????????????c) 如果是meta-class對象伙狐,返回NSObject(基類)的meta-class對象

????3)- (Class)class、+ (Class)class

????????????1> 返回的就是類對象

????????????????- (Class) {

? ? ???????????? ????return self->isa;

?????????????????}

???????????????+ (Class) {

????????????? ??????? return self;

?????????????????}

6瞬欧、反射

????????反射可以理解為類名贷屎、方法名、屬性名等和字符串在運行時相互轉(zhuǎn)化的一種機制

????????實質(zhì) - 發(fā)送了一個消息給Runtime艘虎,然后Runtime再根據(jù)這個Class的字符串名和這個方法的字符串名唉侄,去匹配真正相應(yīng)的方法地址,然后再執(zhí)行野建。同樣反射就是利用字符串去動態(tài)的檢測属划,從而實現(xiàn)運行時的轉(zhuǎn)化。

????????優(yōu)點

????????????????解耦合贬墩,消除類與類之間的依賴

????????缺點

????????????????代碼可讀性降低榴嗅,將原有邏輯復(fù)雜化了,不利于維護

? ? ? ? 性能較差陶舞。使用反射匹配字符串間接命中內(nèi)存比直接命中內(nèi)存的方式要慢嗽测。當然,這個程度取決于使用場景,如果只是作為程序中很少涉及的部分唠粥,這個性能上的影響可以忽略不計疏魏。但是,如果在性能很關(guān)鍵的應(yīng)用核心邏輯中使用反射晤愧,性能問題就尤其重要了)

7大莫、CADisplayLink 與 NSTimer

????CADisplayLink

????????????正常情況下會在每次刷新結(jié)束都被調(diào)用,精確度相當高

????????????使用場合相對專一官份,適合做UI的不停重繪

????NSTimer

????????????精確度就顯得低了點只厘,比如NSTimer的觸發(fā)時間到的時候,runloop如果在阻塞狀態(tài)舅巷,觸發(fā)時間就會推遲到下一個runloop周期

????????????使用范圍要廣泛的多羔味,各種需要單次或者循環(huán)定時處理的任務(wù)都可以使用

8、iOS---------消息轉(zhuǎn)發(fā)機制

? ? ? ? 消息轉(zhuǎn)發(fā)機制的原理 其實就是在內(nèi)部做了三次的補救機會

????????1)動態(tài)解析? 利用runtime動態(tài)添加實現(xiàn)代碼? ?

????????????????resolveInstanceMethod:

????????????????resolveClassMethod:

????????2)快速轉(zhuǎn)發(fā)? 也就是重定向接受者? ? 它會去找其他的類 將消息轉(zhuǎn)發(fā)給可以響應(yīng)該消息的對象進行處理

????????????????- (id)forwardingTargetForSelector:(SEL)aSelector {

????????????????????????????return nil;

????????????????????}

???????3)完整轉(zhuǎn)發(fā)? ? 指定選擇器? IMP指向?qū)崿F(xiàn)代碼

????????????????forwardInvocation

????????_objc_msgForward 函數(shù)是做什么的钠右?直接調(diào)用會發(fā)生什么問題赋元?

? ??????當對象沒有實現(xiàn)某個方法 ,會調(diào)用這個函數(shù)進行方法轉(zhuǎn)發(fā)飒房。 (某方法對應(yīng)的IMP沒找到搁凸,會返回這個函數(shù)的IMP去執(zhí)行)

? ??????1.調(diào)用resolveInstanceMethod:方法,允許用戶在此時為該Class動態(tài)添加實現(xiàn)狠毯。如果有實現(xiàn)了护糖,則調(diào)用并返回。如果仍沒實現(xiàn)垃你,繼續(xù)下面的動作椅文。

? ??????2.調(diào)用forwardingTargetForSelector:方法,嘗試找到一個能響應(yīng)該消息的對象惜颇。如果獲取到,則直接轉(zhuǎn)發(fā)給它少辣。如果返回了nil凌摄,繼續(xù)下面的動作。

? ??????3.調(diào)用methodSignatureForSelector:方法漓帅,嘗試獲得一個方法簽名锨亏。如果獲取不到,則直接調(diào)用doesNotRecognizeSelector拋出異常忙干。

? ??????4.調(diào)用forwardInvocation:方法器予,將地3步獲取到的方法簽名包裝成Invocation傳入,如何處理就在這里面了捐迫。

? ??????如果直接調(diào)用這個方法乾翔,就算實現(xiàn)了想調(diào)用的方法,也不會被調(diào)用,會直接走消息轉(zhuǎn)發(fā)步驟反浓。

9萌丈、UI刷新在主線程

????????UIKit并不是一個線程安全的類,UI操作涉及到渲染訪問各種View對象的屬性雷则,如果異步操作下會存在讀寫問題辆雾,而為其加鎖則會耗費大量資源并拖慢運行速度。

????????整個程序的起點UIApplication是在主線程進行初始化月劈,所有的用戶事件都是在主線程上進行傳遞(如點擊度迂、拖動),所以view只能在主線程上才能對事件進行響應(yīng)猜揪。

????????渲染方面由于圖像的渲染需要以60幀的刷新率在屏幕上同時更新英岭,在非主線程異步化的情況下無法確定這個處理過程能夠?qū)崿F(xiàn)同步更新。在子線程中如果要對UI 進行更新湿右,必須等到該子線程運行結(jié)束才能把UI的更新提交給渲染服務(wù)诅妹。

10、NSObject和id

????????id是一個指針毅人。

????????NSObject *是NSObject類型的指針吭狡。

????????Objective-C中并非所有的類都繼承自NSObject,還有NSProxy類丈莺,故NSObject *的范圍小于id划煮。

11、鎖

????????自旋鎖缔俄、互斥鎖比較 -?

????????????????代碼執(zhí)行頻率高弛秋,CPU充足,可以使用互斥鎖俐载,

????????????????頻率低蟹略,代碼復(fù)雜則需要互斥鎖。

????????自旋鎖 - 等待鎖的進程會處于忙等(busy-wait)狀態(tài)遏佣,一直占用著CPU資源挖炬,目前已經(jīng)不安全,可能會出現(xiàn)優(yōu)先級翻轉(zhuǎn)問題

????????????????自旋鎖在等待時間比較短的時候比較合適

????????????????臨界區(qū)代碼經(jīng)常被調(diào)用状婶,但競爭很少發(fā)生

????????????????CPU不緊張

????????????????多核處理器

????????互斥鎖?- 等待鎖的線程會處于休眠狀態(tài)

????????????????預(yù)計線程等待時間比較長

????????????????單核處理器

????????????????臨界區(qū)IO操作

????????????????臨界區(qū)代碼比較多意敛、復(fù)雜,或者循環(huán)量大

????????????????臨界區(qū)競爭非常激烈

????????遞歸鎖 - 同一個線程可以加鎖N次而不會引發(fā)死鎖

????????mutex? ? :pthread_mutex_t 互斥鎖膛虫,等待鎖的線程會處于休眠狀態(tài)草姻。

????????NSLock ? :對mutex普通鎖的封裝。

????????NSRecursiveLock? ? :對mutex遞歸鎖的封裝稍刀,遞歸鎖可以對相同的線程進行反復(fù)加鎖撩独。

????????NSCondition ? :對mutex和cond的封裝,優(yōu)點是可以讓線程之間形成依賴,缺點是沒有明確的條件跌榔。

????????NSConditionLock? ? :NSCondition的進一步封裝

????????????????可以實現(xiàn)多個子線程進行線程間的依賴异雁,A依賴于B執(zhí)行完成,B依賴于C執(zhí)行完畢則可以使用NSConditionLock來解決問題

????????dispatch_queue ? :特殊的鎖僧须,直接使用GCD的串行隊列纲刀,也是可以實現(xiàn)線程同步的。串行隊列其實就是線程的任務(wù)在隊列中按照順序執(zhí)行担平,達到了鎖的目的示绊。

????????dispatch_semaphore :信號量控制并發(fā)數(shù)量,可以控制并發(fā)線程的數(shù)量暂论,當設(shè)置為1時面褐,可以作為同步鎖來用,設(shè)置多個的時候取胎,就是異步并發(fā)隊列展哭。

????????@synchronized ? :鎖的是對象obj,使用該鎖的時候闻蛀,底層是對象計算出來的值作為key匪傍,生成一把鎖,不同的資源的讀寫可以使用不同obj作為鎖對象觉痛。

????????atmoic ? :原子操作役衡,給屬性添加atmoic修飾,可以保證屬性的setter和getter都是原子性操作薪棒,也就保證了setter和getter的內(nèi)部是線程同步的手蝎。atomic讀取頻率高的時候會導致線程都在排隊,浪費CPU時間

????????讀寫鎖:pthread_rwlock(c語言封裝的讀寫鎖) / 異步柵欄調(diào)用 dispatch_barrier_async

????????性能從高到低排序

????????????????os_unfair_lock

????????????????OSSpinLock

????????????????dispatch_semaphore

????????????????pthread_mutex

????????????????dispatch_queue(DISPATCH_QUEUE_SERIAL)

????????????????NSLock

????????????????NSCondition

????????????????pthread_mutex(recursive)

????????????????NSRecursiveLock

????????????????NSConditionLock

????????????????@synchronized

????????平時簡單使用的話沒有很大的區(qū)別俐芯,還是推薦使用NSLock和信號量,最簡單的是@synchronized棵介,不用聲明和初始化,直接拿來就用泼各。

????????總結(jié)

????????????????普通線程鎖本質(zhì)就是同步執(zhí)行

????????????????atomic原子操作只限制setter和getter方法鞍时,不限制成員變量

????????????????讀寫鎖高性能可以使用pthread_rwlock_t和dispatch_barrier_async

????????死鎖的4個必要條件

????????1、互斥: 某種資源一次只允許一個進程訪問扣蜻,即該資源一旦分配給某個進程,其他進程就不能再訪問及塘,直到該進程訪問結(jié)束莽使。

????????2、占有且等待: 一個進程本身占有資源(一種或多種)笙僚,同時還有資源未得到滿足芳肌,正在等待其他進程釋放該資源。

????????3、不可搶占:別人已經(jīng)占有了某項資源亿笤,你不能因為自己也需要該資源翎迁,就去把別人的資源搶過來。

????????4净薛、循環(huán)等待: 存在一個進程鏈汪榔,使得每個進程都占有下一個進程所需的至少一種資源。

12肃拜、優(yōu)化

CPU

????????盡量用輕量級的對象痴腌,比如用不到事件處理的地方,可以考慮使用CALayer取代UIView

????????不要頻繁地調(diào)用UIView的相關(guān)屬性燃领,比如frame士聪、bounds、transform等屬性猛蔽,盡量減少不必要的修改

????????盡量提前計算好布局剥悟,在有需要時一次性調(diào)整對應(yīng)的屬性,不要多次修改屬性

????????Autolayout會比直接設(shè)置frame消耗更多的CPU資源

????????圖片的size最好剛好跟UIImageView的size保持一致

????????控制一下線程的最大并發(fā)數(shù)量

????????盡量把耗時的操作放到子線程

????????文本處理(尺寸計算曼库、繪制)

????????圖片處理(解碼区岗、繪制)

GPU

????????盡量避免短時間內(nèi)大量圖片的顯示,盡可能將多張圖片合成一張進行顯示

????????GPU能處理的最大紋理尺寸是4096x4096凉泄,一旦超過這個尺寸躏尉,就會占用CPU資源進行處理,所以紋理盡量不要超過這個尺寸

????????盡量減少視圖數(shù)量和層次

????????減少透明的視圖(alpha<1)后众,不透明的就設(shè)置opaque為YES

????????盡量避免出現(xiàn)離屏渲染

????????合理選擇 imageNamed 和 imageWithContentsOfFile

????????imageNamed 會對圖片進行緩存胀糜,適合多次使用某張圖片

????????imageWithContentsOfFile 從bundle中加載圖片文件,不會進行緩存蒂誉,適用于加載一張較大的并且只使用一次的圖片教藻,例如引導圖等

13、[self class] [super class]

????????1右锨、前兩個方法是給self發(fā)送消息, 消息名稱是class和superclass, 結(jié)果很明顯就是查看自己的類型和父類的類型

????????2括堤、后兩個方法也是給self發(fā)送消息, 只不過是從父類開始查詢class和superclass方法, 而這兩個方法都存在于NSObject中

????????3、消息接收者同樣是self, 調(diào)用的方法也是相同, 所以結(jié)果就是自己的類型和父類的類型

14绍移、RunLoop的基本作用

????????1悄窃、保持程序的持續(xù)運行

????????2、處理app中的各種事件(比如觸摸事件蹂窖、定時器事件轧抗、selector事件

????????3、節(jié)省CPU資源瞬测,提高程序性能横媚,有事情就做事情纠炮,沒事情就休息

????????Mode作用 - 指定事件在運行循環(huán)(Loop)中的優(yōu)先級。 線程的運行需要不同的模式灯蝴,去響應(yīng)各種不同的事件恢口,去處理不同情境模式。(比如可以優(yōu)化tableview的時候可以設(shè)置UITrackingRunLoopMode下不進行一些操作)

15穷躁、dealloc包括以下幾個步驟

????????1耕肩、c++析構(gòu)函數(shù)調(diào)用(C++析構(gòu)函數(shù)的作用是用來完成對象被刪除前的一些清理工作,也就是專門的掃尾工作)

????????2折砸、關(guān)聯(lián)對象(例如使用runtime在分類中關(guān)聯(lián)變量)移除看疗,是一個hash表來存儲

????????3、這里進行弱引用表sidetable的相關(guān)釋放操作睦授,包括表的釋放以及引用計數(shù)两芳,即weak指針置為nil的操作就在這里

????????注意 - dealloc方法是對象引用計數(shù)在哪個線程為0,則在哪個線程調(diào)用dealloc方法去枷,所以不一定在主線程執(zhí)行

16怖辆、SideTables 、 SideTable

????????在runtime內(nèi)存空間中删顶,SideTables是一個8個元素長度(長度為64)的hash數(shù)組惕蹄,里面存儲了SideTable洒嗤。SideTables的hash鍵值就是一個對象obj的address凳鬓。一個 obj影钉,對應(yīng)了一個SideTable。但是一個SideTable录粱,會對應(yīng)多個obj腻格。因為SideTable的數(shù)量只有64個,所以會有很多obj共用同一個SideTable

????????在一個SideTable中啥繁,成員:

????????spinlock_t slock ; ????????????? ?//自旋鎖菜职,用于上鎖/解鎖 SideTable。

????????RefcountMap refcnts;? ? ? ? // 對象引用計數(shù)相關(guān) map

????????? ? ? ? (hash map旗闽,其key是obj的地址酬核,而value,則是obj對象的引用計數(shù))

????????????????(僅在未開啟isa優(yōu)化 或 在isa優(yōu)化情況下isa_t的引用計數(shù)溢出時才會用到)

????????weak_table_t weak_table;? ? // 對象弱引用相關(guān) table

????????? ? ? ? (存儲了弱引用obj的指針的地址适室,其本質(zhì)是一個以obj地址為key嫡意,弱引用obj的指針的地址作為value的hash表)


????????Runtime 維護了一個 weak表,用于存儲指向某個對象的所有weak指針捣辆。weak表 其實是一個 hash(哈希)表鹅很,Key 是所指對象的地址,Value是 weak指針 的地址(這個地址的值是所指對象指針的地址)數(shù)組罪帖。

????????1促煮、初始化時:runtime 會調(diào)用 objc_initWeak函數(shù),初始化一個新的 weak指針 指向?qū)ο蟮牡刂贰?/i>

????????2整袁、添加引用時:objc_initWeak函數(shù) 會調(diào)用 objc_storeWeak() 函數(shù)菠齿, objc_storeWeak() 的作用是更新指針指向,創(chuàng)建對應(yīng)的弱引用表坐昙。

????????3绳匀、釋放時,調(diào)用 clearDeallocating函數(shù)炸客。clearDeallocating函數(shù)首先根據(jù)對象地址獲取所有 weak指針地址的數(shù)組疾棵,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設(shè)為 nil,最后把這個 entry 從 weak表中刪除痹仙,最后清理對象的記錄是尔。

17、load 和 initialize

????????+load

????????????????1开仰、+load方法會在runtime加載類拟枚、分類時調(diào)用

????????????????2、每個類众弓、分類的+load恩溅,在程序運行過程中只調(diào)用一次

????????????????3、調(diào)用順序

????????????????????????1)先調(diào)用類的+load

????????????????????????????????按照編譯先后順序調(diào)用(先編譯谓娃,先調(diào)用)?????????

????????????????????????2)調(diào)用子類的+load之前會先調(diào)用父類的+load

????????????????????????3)再調(diào)用分類的+load

????????????????????????????????按照編譯先后順序調(diào)用(先編譯脚乡,先調(diào)用)

????????+initialize

????????? ? ? ?1、 +initialize方法會在類第一次接收到消息時調(diào)用

????????? ? ? ? 2滨达、調(diào)用順序

????????????????? ? ? ? 1奶稠、先調(diào)用父類的+initialize,再調(diào)用子類的+initialize

????????????????????????????????(先初始化父類弦悉,再初始化子類窒典,每個類只會初始化1次)

????????區(qū)別

????????+initialize是通過objc_msgSend進行調(diào)用的,所以有以下特點:

????????? ? ? ? 1稽莉、如果子類沒有實現(xiàn)+initialize瀑志,會調(diào)用父類的+initialize(所以父類的+initialize可能會被調(diào)用多次)

????????? ? ? ? 2、如果分類實現(xiàn)了+initialize污秆,就覆蓋類本身的+initialize調(diào)用

18劈猪、Category

????????實現(xiàn)原理

? ? ? ? 1、Category編譯之后的底層結(jié)構(gòu)是struct category_t良拼,里面存儲著分類的對象方法战得、類方法、屬性庸推、協(xié)議信息

? ? ? ? 2常侦、在程序運行的時候浇冰,runtime會將Category的數(shù)據(jù),合并到類信息中(類對象聋亡、元類對象中)

????????Category和Class Extension的區(qū)別

? ? ? ? 1肘习、Class Extension在編譯的時候,它的數(shù)據(jù)就已經(jīng)包含在類信息中

? ? ? ? 2坡倔、Category是在運行時漂佩,才會將數(shù)據(jù)合并到類信息中

19、能否想向編譯后得到的類中增加實例變量罪塔?能否向運行時創(chuàng)建的類中添加實例變量投蝉?

????????1.不能向編譯后得到的類增加實例變量

????????2.能向運行時創(chuàng)建的類中添加實例變量

解釋

????????1.編譯后的類已經(jīng)注冊在runtime中,類結(jié)構(gòu)體中的objc_ivar_list實例變量的鏈表和instance_size實例變量的內(nèi)存大小已經(jīng)確定, runtime會調(diào)用 class_setvarlayout 或 class_setWeaklvarLayout來處理 strong weak引用.所以不能向存在的類中添加實例變量

????????2.運行時創(chuàng)建的類是可以添加實例變量,調(diào)用class_addIvar函數(shù).但是的在調(diào)用objc_allocateClassPair之后, objc_registerClassPair之前,原因同上.

20、頁面加載速率

????????viewcontroller從viewdidload的第一行到viewdidappear的最后一行所用的時間

21征堪、AutoreleasePool AutoreleasePage

一個AutoreleasePoolPage屬于一個線程瘩缆,一個線程中可以有多個AutoreleasePoolPage

我們可以知道AutoreleasePoolPage底層結(jié)構(gòu)如下:

AutoreleasePoolPage是以棧為結(jié)點通過雙向鏈表的形式組合而成;遵循先進后出規(guī)則请契,整個自動釋放池由一系列的AutoreleasePoolPage組成的咳榜,而AutoreleasePoolPage是以雙向鏈表的形式連接起來。

自動釋放池與線程一一對應(yīng)爽锥;

每個AutoreleasePoolPage對象占用4096字節(jié)內(nèi)存涌韩,其中56個字節(jié)用來存放它內(nèi)部的成員變量,剩下的空間(4040個字節(jié))用來存放autorelease對象的地址氯夷。要注意的是第一頁只有504個對象臣樱,因為在創(chuàng)建page的時候會在next的位置插入1個POOL_SENTINEL。

POOL_BOUNDARY為哨兵對象腮考,入棧時插入雇毫,出棧時釋放對象到此傳入的哨兵對象

每一頁里都存儲了next指針,指向下次新添加的autoreleased對象的位置踩蔚。

每一頁里都包含父節(jié)點和子節(jié)點棚放,分別指向上一頁和下一頁。第一頁的父節(jié)點為nil馅闽,最后一頁的子節(jié)點為nil飘蚯。

每一頁都有一個深度標記,第一頁深度值為0福也,后面的頁面遞增1局骤。

每一頁里還包當前線程、最大入棧數(shù)量暴凑。

AutoreleasePool的內(nèi)存結(jié)構(gòu)如上圖所示峦甩,特點如下:

1)自動釋放池是一個棧的結(jié)構(gòu),是一個以AutoreleasePoolPage為結(jié)點的雙向鏈表现喳,根據(jù)需要來動態(tài)添加或刪除頁面凯傲。

2)每一頁AutoreleasePoolPage的大小為4096字節(jié)犬辰,地址從低到高依次存儲page自身成員、哨兵泣洞、對象指針忧风。其中,自身成員占用56字節(jié)球凰,且哨兵作為對象指針的邊界,在釋放池里只會有一個腿宰,因此:

第一頁呕诉,內(nèi)部存放:page成員 + 1個哨兵 + 504個對象指針。

其它頁吃度,內(nèi)部存放:page成員 + 505個對象指針甩挫。

3)已存滿的頁面被標記為full page,當前正在操作的頁被標記為hot page椿每。

4)AutoreleasePoolPage繼承自AutoreleasePoolPageData伊者,內(nèi)部成員情況如下:

magic:用來校驗AutoreleasePoolPage的結(jié)構(gòu)是否完整。

next :下次新添加的autoreleased對象的位置间护,初始化時指向begin()亦渗。

thread:當前線程,說明自動釋放池和線程有關(guān)聯(lián)汁尺。

parent :指向父節(jié)點法精,即上一個頁面,第一個頁面的parent值為nil痴突。

child:指向子節(jié)點搂蜓,即下一個頁面,最后一個頁面的child值為nil辽装。

depth :表示頁面深度帮碰,從0開始,往后遞增1拾积。

hiwat :即high water mark殉挽,表示最大入棧數(shù)量標記

POOL_BOUNDARY:

只是nil的別名。前世叫做POOL_SENTINEL殷勘,稱為哨兵對象或者邊界對象此再;

POOL_BOUNDARY用來區(qū)分不同的自動釋放池,以解決自動釋放池嵌套的問題

每當創(chuàng)建一個自動釋放池玲销,就會調(diào)用push()方法將一個POOL_BOUNDARY入棧输拇,并返回其存放的內(nèi)存地址;

當往自動釋放池中添加autorelease對象時贤斜,將autorelease對象的內(nèi)存地址入棧策吠,它們前面至少有一個POOL_BOUNDARY逛裤;

當銷毀一個自動釋放池時,會調(diào)用pop()方法并傳入一個POOL_BOUNDARY猴抹,會從自動釋放池中最后一個對象開始带族,依次給它們發(fā)送release消息,直到遇到這個POOL_BOUNDARY

22蟀给、ARC?

在即將超出作用域的時候蝙砌,編譯器會給所有__strong標識的變量調(diào)用一次release

weak也稱為弱引用,弱引用表示并不持有對象跋理,當所引用的對象銷毀了择克,這個變量就自動設(shè)為nil

即使是使用alloc/new/copy/mutableCopy創(chuàng)建的對象,也不持有前普,結(jié)果就是這個對象沒人要肚邢,所以一出來就銷毀了

注意 - 通過非這4個方法創(chuàng)建的對象,并不會因為__weak標識已創(chuàng)建就銷毀拭卿,而是要等到超出autoreleasepool的時候才會銷毀骡湖。

23、sizeThatFits峻厚、sizeToFit

????????sizeThatFits: 會計算出最優(yōu)的 size ,但是不會改變 自己的 size;

????????sizeToFit: 會計算出最優(yōu)的 size 而且會改變自己的 size.

????????Label 文本較長以至于不能單行顯示時响蕴,兩者也是有區(qū)別的

24、SEL IMP

????????SEL - 選擇器目木,代表方法名/函數(shù)名换途,底層結(jié)構(gòu)和char *類似

????????????????可以通過@selector()和sel_registerName()獲得

????????????????可以通過sel_getName()和NSStringFromSelector()轉(zhuǎn)成字符串

????????????????不同類中相同名字的方法名,所對應(yīng)的方法選擇器是相同的

????????IMP - 函數(shù)的具體實現(xiàn)

25刽射、安裝包瘦身

????ipa主要由可執(zhí)行文件军拟、資源組成

? ? ? ? 1、資源(圖片誓禁、音頻懈息、視頻等)

????????????????采取無損壓縮

????????????????去除沒有用到的資源: https://github.com/tinymind/LSUnusedResources

? ? ? ? 2、可執(zhí)行文件瘦身

????????????????編譯器優(yōu)化

Strip Linked Product摹恰、Make Strings Read-Only辫继、Symbols Hidden by Default設(shè)置為YES

????????????????去掉異常支持

Enable C++ Exceptions、Enable Objective-C Exceptions設(shè)置為NO俗慈, Other C Flags添加-fno-exceptions

????????????????利用AppCode(https://www.jetbrains.com/objc/)檢測未使用的代碼:菜單欄 -> Code -> Inspect Code

????????????????編寫LLVM插件檢測出重復(fù)代碼姑宽、未被調(diào)用的代碼

????????

????????????????

????????

????????????????

????????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市闺阱,隨后出現(xiàn)的幾起案子炮车,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘦穆,死亡現(xiàn)場離奇詭異纪隙,居然都是意外死亡,警方通過查閱死者的電腦和手機扛或,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門绵咱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熙兔,你說我怎么就攤上這事悲伶。” “怎么了黔姜?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵拢切,是天一觀的道長。 經(jīng)常有香客問我秆吵,道長,這世上最難降的妖魔是什么五慈? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任纳寂,我火速辦了婚禮,結(jié)果婚禮上泻拦,老公的妹妹穿的比我還像新娘毙芜。我一直安慰自己,他們只是感情好争拐,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布腋粥。 她就那樣靜靜地躺著,像睡著了一般架曹。 火紅的嫁衣襯著肌膚如雪隘冲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天绑雄,我揣著相機與錄音展辞,去河邊找鬼。 笑死万牺,一個胖子當著我的面吹牛罗珍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脚粟,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼覆旱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了核无?” 一聲冷哼從身側(cè)響起扣唱,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后画舌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堕担,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年曲聂,在試婚紗的時候發(fā)現(xiàn)自己被綠了霹购。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡朋腋,死狀恐怖齐疙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旭咽,我是刑警寧澤贞奋,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站穷绵,受9級特大地震影響轿塔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仲墨,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一勾缭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧目养,春花似錦俩由、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至努释,卻和暖如春碘梢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背洽洁。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工痘系, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饿自。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓汰翠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昭雌。 傳聞我的和親對象是個殘疾皇子复唤,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

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