面試題目

1、基礎(chǔ)篇

1、1 ? 屬性和成員變量的區(qū)別 ?

1、11 涉及到的問(wèn)題是類的分類中是否可以添加屬性。

肯定是可以添加的。如果有面試經(jīng)驗(yàn)的人肯定會(huì)被問(wèn)到 是否可以添加屬性和成員變量,這里要注意的是成員變量和屬性是有區(qū)別的(屬性是有set 和get 方法 ,成員變量是沒(méi)有的,屬性是可以用點(diǎn)語(yǔ)法調(diào)動(dòng)的,但是成員變量是使用self-> 來(lái)使用)。那是否可以動(dòng)態(tài)添加成員變量呢,答案是不可以的。因?yàn)镃ategory 是運(yùn)行期決定的,不是編譯期的決定的,所以category是無(wú)法添加實(shí)例變量的(因?yàn)樵谶\(yùn)行期,對(duì)象的內(nèi)存布局已經(jīng)確定,如果添加實(shí)例變量就會(huì)破壞類的內(nèi)部布局,這對(duì)編譯型語(yǔ)言來(lái)說(shuō)是災(zāi)難性的)。那是否不可以添加方法了 ,答案是可以添加方法,因?yàn)镃ategory 有一個(gè)添加方法的數(shù)組(什么?這個(gè)百度去吧)。

1、12 能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量?為什么

不能向編譯后得到的類中增加實(shí)例變量;能向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量;

解釋下:

因?yàn)榫幾g后的類已經(jīng)注冊(cè)在 runtime 中,類結(jié)構(gòu)體中的objc_ivar_list實(shí)例變量的鏈表 和instance_size實(shí)例變量的內(nèi)存大小已經(jīng)確定,同時(shí)runtime 會(huì)調(diào)用class_setIvarLayout或class_setWeakIvarLayout來(lái)處理 strong weak 引用。所以不能向存在的類中添加實(shí)例變量;

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

1、12內(nèi)存管理語(yǔ)義

assign : 只會(huì)執(zhí)行針對(duì) “純量類型”(CGFloat、NSInteger)等。

strong : 擁有關(guān)系,設(shè)置新值時(shí),設(shè)置方法會(huì)先保留新值,并釋放舊值,然后在添加新值設(shè)置上去。 ?

weak :非擁有關(guān)系,設(shè)置新值,不保留新值,也不釋放舊值,和assign類似,但是所指的對(duì)象遭到摧毀時(shí),屬性值也會(huì)清空。

copy: 不保留新值,而是將其拷貝,當(dāng)屬性類型為NSStringn*時(shí),經(jīng)常用此特質(zhì)來(lái)保護(hù)期封裝性。NSMutableString 是NSString 的子類,可以修改值。

copy:涉及到內(nèi)容復(fù)制和地址復(fù)制。copy 涉及到問(wèn)題 ,先給出答案,

[immutableObject copy] // 淺復(fù)制

[immutableObject mutableCopy] //深復(fù)制

[mutableObject copy] //深復(fù)制

[mutableObject mutableCopy] //深復(fù)制?

這里所說(shuō)的復(fù)制是指,指針的地址復(fù)制,不是指針?biāo)赶虻膶?duì)象的地址復(fù)制。舉個(gè)例子

NSArray *array2 = @[ @1, @2, @3, @4 ];

NSLog(@"array2===%p==",&array2); ?(指針?biāo)赶驅(qū)ο蟮闹?

NSLog(@"array2===%p==",array2); (指針的值)


如果在多層數(shù)組中,對(duì)第一層進(jìn)行內(nèi)容拷貝,其它層進(jìn)行指針拷貝,這種情況是屬于深復(fù)制,還是淺復(fù)制? 這個(gè)是 集合的單層深復(fù)制


1、3 IMP 和SEL 的區(qū)別

SEL : 類成員方法的指針,但不同于C語(yǔ)言中的函數(shù)指針,函數(shù)指針直接保存了方法的地址,但SEL只是方法編號(hào)。

IMP:一個(gè)函數(shù)指針,保存了方法的地址

編號(hào)SEL最后還是要通過(guò)Dispatch table表尋找到對(duì)應(yīng)的IMP,IMP就是一個(gè)函數(shù)指針,然后執(zhí)行這個(gè)方法

2、中級(jí)偏篇

2.1 objc_msgSend 傳遞消息

objc_msgSend 是傳遞消息,如果向某對(duì)象傳遞消息,那就會(huì)使用動(dòng)態(tài)綁定機(jī)制來(lái)決定需要調(diào)用的方法。給對(duì)象發(fā)送消息可以這樣來(lái)寫:

id returnValue = [someObject messageName:parameter];

在本例中,someObject叫做 “接受者,messageName叫做 “選擇子””,選擇子和參數(shù)合起來(lái)稱為“消息”。編譯器看到此消息后,將其轉(zhuǎn)換成一條標(biāo)準(zhǔn)的C語(yǔ)言函數(shù)調(diào)用,所調(diào)用的函數(shù)乃是消息傳遞機(jī)制中的核心函數(shù),叫做 object_msgSend,?

void objc_msgSend(id self,SEL cmd, ...)

接收者所屬的類中搜尋其“方法列表 (list of methods)” ,如果能找到與選擇子名稱相符的方法,就跳至其實(shí)現(xiàn)代碼。若是找不到,那就沿著繼承體系繼續(xù)向上查找,等找到合適的方法之后再跳轉(zhuǎn)。如果最終還是找不到相符的方法,那就執(zhí)行“消息轉(zhuǎn)發(fā)”的操作。

objc_msgSend 會(huì)將匹配結(jié)果緩存在 “快速映射表”里面,每個(gè)類都有這樣一塊緩存,若是稍后還向該類發(fā)送與選擇子相同的消息,那么執(zhí)行起來(lái)就很快了。

?2.2 消息轉(zhuǎn)發(fā)(message forwarding)

在編譯期向類發(fā)送了期無(wú)法解讀的消息并不會(huì)報(bào)錯(cuò),因?yàn)樵谶\(yùn)行期可以繼續(xù)向類中添加方法,所以編譯器在編譯時(shí)還無(wú)法確定知道到底會(huì)不會(huì)有某個(gè)方法實(shí)現(xiàn)。當(dāng)對(duì)象接收到無(wú)法解讀的消息后,就會(huì)啟動(dòng)“消息轉(zhuǎn)發(fā)”機(jī)制,程序員可經(jīng)由此過(guò)程告訴對(duì)象應(yīng)該如何處理未知消息。(unrecognized seletor sent to instance) 這個(gè)是平常開(kāi)發(fā)中遇到的一個(gè)問(wèn)題,方法識(shí)別不了,

消息轉(zhuǎn)發(fā)分為兩大階段:第一階段先征詢接收者,所屬的類,看其是否能動(dòng)態(tài)添加方法,以處理當(dāng)期這個(gè) “未知的選擇子”,這叫做“動(dòng)態(tài)方法解析”。第二階段涉及“完整的消息轉(zhuǎn)發(fā)機(jī)制”,第一階段執(zhí)行完說(shuō)明,接收對(duì)象無(wú)法動(dòng)態(tài)添加方法。此時(shí),運(yùn)行期系統(tǒng)會(huì)請(qǐng)求接收者以其他手段來(lái)處理與消息相關(guān)的方法調(diào)用。這又細(xì)分兩小步。首先,請(qǐng)接收者看看有沒(méi)有其他對(duì)象來(lái)處理這條消息,如果有,把這條消息轉(zhuǎn)給那個(gè)對(duì)象,于是消息轉(zhuǎn)發(fā)過(guò)程結(jié)束,一切如常。如果沒(méi)有備援的接收者,則啟動(dòng)完成的消息轉(zhuǎn)發(fā)機(jī)制,運(yùn)行期系統(tǒng)會(huì)把與消息有關(guān)的全部細(xì)節(jié)都封裝到NSInvocation 對(duì)象中,再給接收者最后一次機(jī)會(huì),讓接收者設(shè)法解決當(dāng)前還未處理的這條消息。 找一張網(wǎng)上的圖片。


問(wèn)題 :每個(gè)類中都有一個(gè)方法列表?

2.3 Block

2.31 block的實(shí)質(zhì)是什么?一共有幾種block?都是什么情況下生成的?

block 就是一種代替函數(shù)指針的語(yǔ)法結(jié)構(gòu),原來(lái)使用函數(shù)指針時(shí),需要用“不透明的void指針”來(lái)傳遞狀態(tài),block 一共有三種:全局塊,堆塊,棧塊,

2.32 為什么在默認(rèn)情況下無(wú)法修改被block捕獲的變量? __block都做了什么?

沒(méi)有加__block ,是傳值 ,加了__block 是傳地址。詳情看這個(gè)(http://www.cnblogs.com/HypeCheng/p/4597205.html)。

2.33 模擬一下循環(huán)引用的一個(gè)情況?block實(shí)現(xiàn)界面反向傳值如何實(shí)現(xiàn)?

2.34 block 為什么需要添加copy?

沒(méi)有添加copy block是在棧,添加了copy 是復(fù)制到堆區(qū),棧是在內(nèi)存中是一塊連續(xù)的存儲(chǔ)空間,堆在內(nèi)存中是分散的,是全局的,所以,使用范圍就變大了。棧區(qū)是系統(tǒng)負(fù)責(zé)回收的,而堆區(qū)一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收,分配方式倒是類似于鏈表,所以 如果不使用Copy,block 回收的時(shí)候,你都不知道。

2.35 SDWebImage 在tableView 中加載大量圖片,如何保證加載后的圖片是對(duì)應(yīng)相應(yīng)的URL,不會(huì)錯(cuò)位顯示圖片。

Runtime

objc在向一個(gè)對(duì)象發(fā)送消息時(shí),發(fā)生了什么?

什么時(shí)候會(huì)報(bào)unrecognized selector錯(cuò)誤?iOS有哪些機(jī)制來(lái)避免走到這一步?

能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量?為什么?

runtime如何實(shí)現(xiàn)weak變量的自動(dòng)置nil?

給類添加一個(gè)屬性后,在類結(jié)構(gòu)體里哪些元素會(huì)發(fā)生變化?


http://nshipster.cn/method-swizzling/


2.4 iOS下所有的本地持久化方?

三、RunLoop

3.1 runloop是來(lái)做什么的?runloop和線程有什么關(guān)系?主線程默認(rèn)開(kāi)啟了runloop么?子線程呢?

run loop和線程是緊密相連的,可以這樣說(shuō)run loop是為了線程而生,沒(méi)有線程,它就沒(méi)有存在的必要, 主線程默認(rèn)是開(kāi)啟了runloop的,子線程需要自己手動(dòng)配置和開(kāi)啟。

runloop的mode是用來(lái)做什么的?有幾種mode?

3.2 model 主要是用來(lái)指定事件在運(yùn)行循環(huán)中的狀態(tài),NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認(rèn),空閑狀態(tài)UITrackingRunLoopMode:ScrollView滑動(dòng)時(shí)

UIInitializationRunLoopMode:?jiǎn)?dòng)時(shí)NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合

蘋果公開(kāi)提供的 Mode 有兩個(gè):

NSDefaultRunLoopMode(kCFRunLoopDefaultMode)NSRunLoopCommonModes(kCFRunLoopCommonModes)


3.3 為什么把NSTimer對(duì)象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)以后,滑動(dòng)scrollview的時(shí)候NSTimer卻不動(dòng)了?

model 由NSDefaultRunLoopMode 切換到UITrackingRunLoopMode的時(shí)候,NSTimer 就失效了,scrollview就生效了。

model 只能存在一種類型,換成 NSRunLoopCommonModes model 就可以。

蘋果是如何實(shí)現(xiàn)Autorelease Pool的?


3.4 動(dòng)畫

1、隱式動(dòng)畫:

核心動(dòng)畫的隱式動(dòng)畫模型假定所有動(dòng)畫圖層屬性的變化應(yīng)該是漸進(jìn)的和異步的。動(dòng)態(tài)的動(dòng)畫場(chǎng)景可以在沒(méi)有顯式的動(dòng)畫圖層時(shí)候?qū)崿F(xiàn)。改變動(dòng)畫顯示的圖層的屬性將會(huì)導(dǎo)致圖層隱式把舊值動(dòng)畫顯示為新值,雖然動(dòng)畫是持續(xù)的,但是設(shè)置新的目標(biāo)值會(huì)導(dǎo)致圖層從當(dāng)前狀態(tài)動(dòng)畫過(guò)度到新的目標(biāo)值

OrderSearchVC *search = [[OrderSearchVC alloc] init];? ? [self.navigationController pushViewController:search animated:YES];

2、顯式動(dòng)畫:

核心動(dòng)畫同事提供了一個(gè)顯示動(dòng)畫模型。該顯式動(dòng)畫模型需要你創(chuàng)建一個(gè)動(dòng)畫對(duì)象,并設(shè)置開(kāi)始值和結(jié)束的值,顯示動(dòng)畫不會(huì)開(kāi)始執(zhí)行,直到你把該動(dòng)畫應(yīng)用到某個(gè)圖層上面

四、類結(jié)構(gòu)

4.1 isa指針?(對(duì)象的isa,類對(duì)象的isa,元類的isa都要說(shuō))

對(duì)象isa :實(shí)例所屬的類。

類對(duì)象的isa:類對(duì)象指針isa所指向的類型是另外一個(gè)雷,叫做“元類”,表述類對(duì)象本身所具備的元數(shù)據(jù)(類對(duì)象的實(shí)例方法)。

4.2 類方法和實(shí)例方法有什么區(qū)別?

4.3 介紹一下分類,能用分類做什么??jī)?nèi)部是如何實(shí)現(xiàn)的?它為什么會(huì)覆蓋掉原來(lái)的方法?

1)、category的方法沒(méi)有“完全替換掉”原來(lái)類已經(jīng)有的方法,也就是說(shuō)如果category和原來(lái)類都有methodA,那么category附加完成之后,類的方法列表里會(huì)有兩個(gè)methodA

2)、category的方法被放到了新方法列表的前面,而原來(lái)類的方法被放到了新方法列表的后面,這也就是我們平常所說(shuō)的category的方法會(huì)“覆蓋”掉原來(lái)類的同名方法,這是因?yàn)檫\(yùn)行時(shí)在查找方法的時(shí)候是順著方法列表的順序查找的,它只要一找到對(duì)應(yīng)名字的方法,就會(huì)罷休^_^,殊不知后面可能還有一樣名字的方法

4.4 運(yùn)行時(shí)能增加成員變量么?能增加屬性么?如果能,如何增加?如果不能,為什么?

?這個(gè)問(wèn)題和在分類中處于編譯期間添加實(shí)例變量 和在運(yùn)行時(shí)添加編譯實(shí)例變量 有啥區(qū)別?????

4.5 objc中向一個(gè)nil對(duì)象發(fā)送消息將會(huì)發(fā)生什么?(返回值是對(duì)象,是標(biāo)量,結(jié)構(gòu)體)

4.6 GCD

4.61 你碰到過(guò)死鎖的問(wèn)題嗎?

同步+主隊(duì)列 會(huì)死鎖


五、高級(jí)

5.1 UITableview的優(yōu)化方法(緩存高度,異步繪制,減少層級(jí),hide,避免離屏渲染)

5.2 有沒(méi)有用過(guò)運(yùn)行時(shí),用它都能做什么?(交換方法,創(chuàng)建類,給新創(chuàng)建的類增加方法,改變isa指針)

5.3 看過(guò)哪些第三方框架的源碼?都是如何實(shí)現(xiàn)的?(如果沒(méi)有,問(wèn)一下多圖下載的設(shè)計(jì))

5.4 SDWebImage的緩存策略?

內(nèi)存和硬盤緩存策略。

5.4.1 SDWebImage 清除圖片的策略是怎么樣的。

5.5 AFN為什么添加一條常駐線程?

?為了線程保活

5.6 KVO的使用?實(shí)現(xiàn)原理?(為什么要?jiǎng)?chuàng)建子類來(lái)實(shí)現(xiàn))

5.7 KVC的使用?實(shí)現(xiàn)原理?(KVC拿到key以后,是如何賦值的?知不知道集合操作符,能不能訪問(wèn)私有屬性,能不能直接訪問(wèn)_ivar)

5.8 事件傳遞

http://www.lxweimin.com/p/2e074db792ba 很詳細(xì)。

5.8 initialize和load 的區(qū)別。

在加載階段,如果類實(shí)現(xiàn)了load方法,系統(tǒng)就會(huì)調(diào)用,分類也可以定義此方法,類的load方法要比分類中的先調(diào)用。與其他方法不同,load方法不參與覆寫機(jī)制,

initialize和load 都是只執(zhí)行一次,但是load 是一定會(huì)調(diào)用的,initialize是類用到了才會(huì)調(diào)用類的initialize,load是應(yīng)用程序必須阻塞并等著所有類的load都執(zhí)行完,才能繼續(xù)。

執(zhí)行l(wèi)oad方法時(shí)候,程序是阻塞狀態(tài),但是執(zhí)行initialize的時(shí)候是正常狀態(tài)。

load 不遵循繼承關(guān)系,子類的load執(zhí)行要等他的父類執(zhí)行完之后才可以執(zhí)行。

initialize 遵循繼承關(guān)系。

5.9 日常中開(kāi)發(fā)中你遇到的最多的Crash 是什么,你是怎么解決的。

數(shù)組、字典的Crash 就不要說(shuō)了,這樣顯的你太low了,這個(gè)是個(gè)開(kāi)放的問(wèn)題,沒(méi)有什么具體的答案,下面列舉本人開(kāi)發(fā)中遇到的Crash 文件。

5.91、EXC_BAD_ACCESS 野指針,最常見(jiàn)的原因是在初始化方法中初始化變量時(shí)用錯(cuò)了所有權(quán)修飾符,這會(huì)導(dǎo)致對(duì)象釋放。

5.92、SIGSEGV 段錯(cuò)誤信號(hào)是操作系統(tǒng)產(chǎn)生的一個(gè)更嚴(yán)重的問(wèn)題。當(dāng)硬件出現(xiàn)錯(cuò)誤,訪問(wèn)不可讀的內(nèi)存地址或受保護(hù)的內(nèi)存地址寫入數(shù)據(jù)時(shí),就會(huì)發(fā)生這個(gè)錯(cuò)誤。

5.93 ?SIGBUG

5.94 SIGTRAP

5.95 EXC_ARITHMETIC

5.60 SIGILL

5.61 SIGABRT

6.0你項(xiàng)目中的日活和注冊(cè)用戶是多少。


?未完 慢慢更新,加班之后才嘗試寫文章

參考文獻(xiàn):

https://juejin.im/post/5938dfdb8d6d810058481572

https://github.com/ChenYilong/iOSInterviewQuestions

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1.什么是arc?(arc是為了解決什么問(wèn)題誕生的?) 首先解釋ARC: automatic reference ...
    LuckTime閱讀 410評(píng)論 0 0
  • Objective-C是一門動(dòng)態(tài)的語(yǔ)言 ① 什么是動(dòng)態(tài)語(yǔ)言? 動(dòng)態(tài)語(yǔ)言,是指程序在運(yùn)行時(shí)可以改變其結(jié)構(gòu):新的函數(shù)可...
    小李龍彪閱讀 385評(píng)論 0 0
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,217評(píng)論 30 472
  • 很小的時(shí)候,曾在天的半邊看到過(guò)落日歸霞的場(chǎng)景。如今,雖能再見(jiàn),可卻少了一點(diǎn)喜悅,半分激情。唯多的只有滿滿的懷念。 ...
    琦棟閱讀 273評(píng)論 2 2
  • 今天我想說(shuō)說(shuō)我的朋友圈,我手機(jī)上的朋友圈每天都很熱鬧,什麼樣的人都有,什麼樣的職業(yè)都有,分享出來(lái)的東西都不一樣啊 ...
    一棵樹(shù)閱讀 195評(píng)論 0 0