基礎(chǔ)面試題:
1. copy 和 strong 的區(qū)別。
也就是 深拷貝和淺拷貝 的區(qū)別。 copy屬于深拷貝 其性質(zhì)是開辟新的內(nèi)存空間指向新的值,不同的內(nèi)存地址互不干涉,使? copy 的?的是為了讓本對(duì)象的屬性不受外界影響。strong屬于淺拷貝 那么這個(gè)屬性就有可能指向?個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性
常會(huì)被問到!?。?/p>
1.? NSMutableArray為什么不可以用 copy 修飾?
其原因是:在調(diào)用self.數(shù)組? 增刪改 系統(tǒng)方法的時(shí)候會(huì)奔潰。 copy 修飾的? NSMutableArray的數(shù)組會(huì)被當(dāng)成? NSArray 不可變數(shù)組執(zhí)行, 當(dāng)self 調(diào)用底層的 get/set 方法時(shí)候 沒有響應(yīng)的增刪改方法。所以會(huì)奔潰。
經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,他們之間可能進(jìn)行賦值操作!
2. NSString 為什么用copy 修飾?
? ? ? 使用copy修飾之后,即使屬性拷貝來自可變字符串,也會(huì)被深拷貝成不可變字符串, 例如在字符串a(chǎn)ppendString 拼接或者是等等操作時(shí)。開辟的是另一塊新的內(nèi)存空間、修改前的值不會(huì)隨著修改后的值而發(fā)生變化。所以為了避免可變字符串類型的值被修改用copy
weak 和 assign 的區(qū)別:
weak:? 只可以修飾對(duì)象、不會(huì)產(chǎn)生野指針,釋放后指針會(huì)被置為 nil , 之后再向該對(duì)象發(fā)送消息也不會(huì)奔潰
assign: 既可以修飾對(duì)象也可以修飾基本數(shù)據(jù)類型。 修飾對(duì)象會(huì)產(chǎn)生野指針、釋放后不會(huì)置為 nil ,發(fā)送消息會(huì)奔潰
2. 關(guān)于常見的block問題
1. block 為什么用copy修飾?
2. _ _ block 為什么可以修改block變量
3. 關(guān)于block 循環(huán)引用的問題
來自內(nèi)心靈魂深處的三問?。?!
block 為什么用copy修飾?
首先得理解 堆和棧 的關(guān)系!? 堆是程序員 手動(dòng)的分配和釋放內(nèi)存、棧是由 系統(tǒng)分配釋放內(nèi)存。
說到在類中聲明一個(gè)block為什么要用copy修飾的話,那就要先說block的三種類型
1> NSGlobalBlock 全局block?? 不會(huì)訪問外部的變量! 就說你的block沒有調(diào)用其他外部的變量,那么你的block就是這種,例如: 你的block 只寫一個(gè)了個(gè)NSLog的輸出
2> NSStaticBlock 保存在棧上的block,當(dāng)函數(shù)返回時(shí)被銷毀。這個(gè)block申請(qǐng)不用copy修飾,并且你的block訪問了外部變量
3> NSMallocBlock 保存在堆中的block,當(dāng)引用計(jì)數(shù)為0時(shí)會(huì)銷毀,也就是用copy修飾的blcok
我們知道,函數(shù)的聲明周期是隨著函數(shù)調(diào)用的結(jié)束就終止了。我們的block是寫在函數(shù)中的。
如果是全局靜態(tài)block的話,他直到程序結(jié)束的時(shí)候,才會(huì)被被釋放。但是我們實(shí)際操作中基本上不會(huì)使用到不訪問外部變量的block。
如果是保存在棧中的block,他會(huì)隨著函數(shù)調(diào)用結(jié)束被銷毀。從而導(dǎo)致我們?cè)趫?zhí)行一個(gè)包含block的函數(shù)之后,就無法再訪問這個(gè)block。因?yàn)椋ê瘮?shù)結(jié)束,函數(shù)棧就銷毀了,存在函數(shù)里面的block也就沒有了),我們?cè)偈褂胋lock時(shí),就會(huì)產(chǎn)生空指針異常。
如果是堆中的block,也就是copy修飾的block。他的生命周期就是隨著對(duì)象的銷毀而結(jié)束的。只要對(duì)象不銷毀,我們就可以調(diào)用的到在堆中的block。
這就是為什么我們要用copy來修飾block。因?yàn)椴挥胏opy修飾的訪問外部變量的block,只在他所在的函數(shù)被調(diào)用的那一瞬間可以使用。之后就消失了。
_ _ block 為什么可以修改block變量 ?
__block修飾之后是將變量的內(nèi)存地址傳進(jìn)去,Block捕獲時(shí),記錄了該變量的地址。所以后續(xù)該變量的值改變了,block調(diào)用時(shí),通過地址獲取到的值仍然是最新的值
關(guān)于block 循環(huán)引用的問題 ?
一個(gè)對(duì)象中強(qiáng)引用了block,在block中又強(qiáng)引用了該對(duì)象,就會(huì)發(fā)射循環(huán)引用。
block中使用self,self.xxBlcok或者成員變量block? 導(dǎo)致了循環(huán)引用 。 __weakSelf來代替self解決等。? __weak __tyof (self) weakselfi =? self
這里常常會(huì)有一個(gè)延伸:? 問的是AFNetWorking 中的Block使用怎么會(huì)不引起循環(huán)引用?
AF3.0 一下? AFURLConnectionOperation 里的一個(gè)請(qǐng)求結(jié)束之后,setCompleteBlock會(huì)把block設(shè)置為nil,來打破循環(huán)引用 .
所謂循環(huán)引用,是因?yàn)楫?dāng)前控制器在引用著block,而block又引用著self即當(dāng)前控制器,這樣就造成了循環(huán)引用。AFN中的block的調(diào)用并不在當(dāng)前控制器中調(diào)用,那么這個(gè)self就不代表當(dāng)前控制器,那自然也就沒有循環(huán)引用的問題
3. ios13適配問題
1. 私有方法 KVC 可能導(dǎo)致崩潰。在 iOS 13 中部分方法屬性不允許使用 valueForKey、setValue:forKey:? 來獲取或者設(shè)置私有屬性,具體表現(xiàn)為在運(yùn)行時(shí)會(huì)直接崩潰
2. 使用 presentViewController 方式打開視圖,默認(rèn)的如下圖所示的視差效果,通過下滑返回。解決方法就是將? ? modalPresentationStyle? 改回 Fullscreen 樣式
3.MPMoviePlayerController 被棄用
4.在 iOS 13 中,蘋果將原來藍(lán)牙申請(qǐng)權(quán)限用的 NSBluetoothPeripheralUsageDescription 字段,替換為 NSBluetoothAlwaysUsageDescription 字段。
5. 第三方登錄中心必須接入蘋果登錄
等等有一些導(dǎo)航欄 搜索框的改變 這上面我就不一一列舉了。有心得同學(xué)可以自己去查閱一下文檔
4. Runloop的簡(jiǎn)單理解
第一次獲取時(shí)被創(chuàng)建、線程結(jié)束被銷毀。? 多線程時(shí)? 主線程默認(rèn)開啟? 子線程的手動(dòng)開啟
? ? ? ? ? ? ? ? ? [NSRunLoop currentRunLoop]
概念: 運(yùn)行循環(huán)機(jī)制。內(nèi)部是一個(gè)do-while 循環(huán),在這個(gè)循環(huán)內(nèi)部不斷處理各種任務(wù), RunLoop存在的目的就是當(dāng)線程中有任務(wù)的時(shí)候,保證線程干活,當(dāng)線程沒有任務(wù)的時(shí)候,讓線程睡眠,提高程序性能,節(jié)省資源,該做事的時(shí)候做事,該休息的時(shí)候休息
作用: 1>? 保持程序持續(xù)運(yùn)行
???????????? 2>? 處理App中各類事件 (事件響應(yīng)、手勢(shì)識(shí)別、界面刷新、自動(dòng)釋放池、等事件處理)
???????????? 3> 節(jié)省資源,提高程序性能
這邊有一個(gè)延伸問題:? UIScrollView 的滾動(dòng)會(huì)導(dǎo)致 NSTimer 失效為什么?
在tableview滑動(dòng)時(shí)timer就是顯示暫停,原因是timer的這個(gè)簡(jiǎn)便構(gòu)造方法把timer加入了NSRunLoopDefaultMode上,而tableview在滑動(dòng)時(shí)只會(huì)處理UITrackingRunLoopMode,也就是說當(dāng)前的RunLoop并沒有功夫處理timer事件。? 指定消息循環(huán)的模式為CommonModes(無論runloop運(yùn)行在哪個(gè)mode,都能運(yùn)行)
- kCFRunLoopDefaultMode, App的默認(rèn)運(yùn)行模式,通常主線程是在這個(gè)運(yùn)行模式下運(yùn)行
- UITrackingRunLoopMode, 跟蹤用戶交互事件(用于 ScrollView 追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他Mode影響)-
kCFRunLoopCommonModes, 偽模式,不是一種真正的運(yùn)行模式- UIInitializationRunLoopMode:在剛啟動(dòng)App時(shí)第進(jìn)入的第一個(gè)Mode,啟動(dòng)完成后就不再使用
- GSEventReceiveRunLoopMode:接受系統(tǒng)內(nèi)部事件,通常用不到
注意iOS 對(duì)以上5中model進(jìn)行了封裝NSDefaultRunLoopMode;NSRunLoopCommonModes
為什么說提高了性能?
因?yàn)樵跊]有事件發(fā)生的時(shí)候處于休眠狀態(tài),有事件發(fā)生的時(shí)候處于工作狀態(tài) 。
5.? SDWebimage 原理相關(guān)問題?。?!
? 我這里只做一個(gè)簡(jiǎn)述。 只針對(duì)面試可能遇到的一些提問。具體問題你可以去查詢一下源碼或者找一些大神的博客看一看。
其作用:? 就是圖片的下載、緩沖、下載進(jìn)度監(jiān)控。
1. 緩沖圖片的名稱? MD5? 為防止重名
2.內(nèi)存警告是如何處理的 ?? 利用通知中心觀察 、clear Memory清理內(nèi)存緩沖 clear Disk 清理磁盤緩沖。
3.緩沖時(shí)間是一周
4.clear和clean的區(qū)別?
? clear 連同緩沖文件夾刪除、再創(chuàng)建一個(gè)新的。clean 先刪除過期的文件、再計(jì)算緩沖大小刪除、按照創(chuàng)建時(shí)間刪除知道m(xù)axsize
5.默認(rèn)緩沖文件路徑? :? default下? 6. 最大并發(fā)數(shù)6條? 7.超時(shí)時(shí)間15S? 8.緩沖機(jī)制:NSCache
SDWebimage的工作流程:
? 1.? setImageWithURL? 先設(shè)置請(qǐng)求網(wǎng)址和占位圖片
? 2.? 先從內(nèi)存圖片查找圖片, 如果查到回調(diào)到 SDWebImaFFgeManage中顯示圖片
? 3.? 如果有沒查到就 生成opeartion 添加到隊(duì)列查找磁盤、根據(jù) URLKey從緩沖目錄讀取。讀取到添加到內(nèi)存緩沖中、再回調(diào)到manage類中展示
? 4. 如果沒換沒有查詢到 就重新下載
? 5. 下載完的圖片加入緩存中,并寫入到磁盤中;
? 6.整個(gè)獲取圖片的過程是在子線程中進(jìn)行,在主線程中顯示。
6. weak如何實(shí)現(xiàn)自動(dòng)賦nil?
runtime 對(duì)注冊(cè)的類會(huì)進(jìn)行布局,weak對(duì)象會(huì)被放到一個(gè)弱引用的hash表中。用weak指向的對(duì)象內(nèi)存地址作為key。當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候dealloc,在這個(gè)weak表中搜索找到所有以key為鍵weak的對(duì)象從而設(shè)置為nil
7.自動(dòng)釋放池問題
? 常用到是for循環(huán)創(chuàng)建大量變量的時(shí)候 !?。?/p>
每次調(diào)用每次都會(huì)創(chuàng)建一個(gè)新的對(duì)象。如果不是通過alloc、new、copy等創(chuàng)建的,那么他們的內(nèi)部都會(huì)有一個(gè)autorelease進(jìn)行自動(dòng)釋放,會(huì)等到循環(huán)結(jié)束進(jìn)行釋放而此時(shí)會(huì)消耗大量?jī)?nèi)存資源造成內(nèi)存溢出。運(yùn)行緩慢 。autorelease實(shí)際上只是把對(duì)release的調(diào)?延遲了,對(duì)于每?個(gè)autorelease,系統(tǒng)只是把該Object放?了當(dāng)前的Autorelease pool中,runloop結(jié)束或者作用域超出{}或者超出[pool release]之后再被釋放
@autoreleasepool? 可以完美的解決
8.? 涉及到地圖持續(xù)定位耗電問題解決方案
? 原因是:持續(xù)的調(diào)用didupdatelocation方法
解決方案“:
1. 距離過濾器? distanceFilter 指定距離調(diào)用代理方法
2. 設(shè)置精確度? 通過計(jì)算過程的降低達(dá)到省電
9. set/get? 方法返回self屬性奔潰
self.? 實(shí)際上相當(dāng)于 set/get 的調(diào)用。? 導(dǎo)致循環(huán)調(diào)用? 所以會(huì)奔潰
11. KVO原理
因?yàn)闀r(shí)間問題我就不貼代碼了。只是將KVO建立觀察者后 的一個(gè)流程梳理一下。
1、利用RuntimeAPI動(dòng)態(tài)生成一個(gè)子類NSKVONotifying_XXX,并且讓instance對(duì)象的isa指向這個(gè)全新的子類
2、當(dāng)修改對(duì)象的屬性時(shí),會(huì)在子類NSKVONotifying_XXX調(diào)用Foundation的_NSSetXXXValueAndNotify函數(shù)
3、在_NSSetXXXValueAndNotify函數(shù)中依次調(diào)用
? 1)? willChangeValueForKey? ? ? ? 2)父類原來的setter? ? 3)didChangeValueForKey,didChangeValueForKey:內(nèi)部會(huì)觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法( observeValueForKeyPath:ofObject:change:context:)
? ? 2、如何手動(dòng)觸發(fā)KVO方法
手動(dòng)調(diào)用willChangeValueForKey和didChangeValueForKey方法
? 3、直接修改成員變量會(huì)觸發(fā)KVO嗎
不會(huì)觸發(fā)KVO,因?yàn)镵VO的本質(zhì)就是監(jiān)聽對(duì)象有沒有調(diào)用被監(jiān)聽屬性對(duì)應(yīng)的setter方法,直接修改成員變量,是在內(nèi)存中修改的,不走set方法
4、不移除KVO監(jiān)聽,會(huì)發(fā)生什么
不移除會(huì)造成內(nèi)存泄漏但是多次重復(fù)移除會(huì)崩潰。系統(tǒng)為了實(shí)現(xiàn)KVO,為NSObject添加了一個(gè)名為NSKeyValueObserverRegistration的Category,KVO的add和remove的實(shí)現(xiàn)都在里面。在移除的時(shí)候,系統(tǒng)會(huì)判斷當(dāng)前KVO的key是否已經(jīng)被移除,如果已經(jīng)被移除,則主動(dòng)拋出一個(gè)NSException的異常
5. 如何手動(dòng)關(guān)閉kvo
重寫被觀察對(duì)象的automaticallyNotifiesObserversForKey方法,返回NO重寫automaticallyNotifiesObserversOf ,返回NO ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? 注意:關(guān)閉kvo后,需要手動(dòng)在賦值前后添加willChangeValueForKey和didChangeValueForKey,才可以收到觀察通知。
11.? delegate 代理用weak 修飾?
weak修飾對(duì)象只指向?qū)ο?,并不保持delegate對(duì)象,釋放由外部控制
strong該對(duì)象強(qiáng)引用delegate對(duì)象,形成穩(wěn)妥對(duì)象和被委托對(duì)象相互擁有,由于外部不能銷毀而導(dǎo)致引起循環(huán)引用問題。
12. 關(guān)于圖片的上傳和壓縮問題
AF中的 AFHTTPSessionManager就可以實(shí)現(xiàn)。主要涉及的就是如果是多張圖上傳50張、500張考慮一個(gè)占用內(nèi)存過大而崩潰的問題,可以通過加到自動(dòng)釋放池解決。
壓縮問題:? 例如傳的圖片大、耗時(shí)? 耗流量
可以通過 UIImageJPERepresontation方法??梢栽O(shè)置壓縮指數(shù)。 例如加入判斷? image>1M 壓縮指數(shù)設(shè)置為0.7? 0.5M<imahe<1M 調(diào)整成0.8? 小于0.5M 寫成0.9或者1 都可以
13.TableView優(yōu)化
1.提前計(jì)算好cell的高度和布局(因?yàn)閠ableview回調(diào)的時(shí)候會(huì)多次的調(diào)用heightForRow的方法),獲取數(shù)據(jù)的時(shí)候計(jì)算cell,保存到對(duì)應(yīng)的model中,調(diào)用行高直接獲取model 就行
2..加載網(wǎng)絡(luò)數(shù)據(jù),下載圖片,使用異步加載,并緩存
3.滑動(dòng)時(shí)按需加載對(duì)應(yīng)的內(nèi)容,
4.使用局部更新(如果只是更新某組的話,使用reloadSection進(jìn)行局部更)
14.性能優(yōu)化
1. 頁面布局:? 對(duì)象的創(chuàng)建、銷毀(廣播、定時(shí)器等等),文本控件的計(jì)算排版等等
1.2 盡量使用純代碼開發(fā)。?避免龐大的xib,storyBoard 因?yàn)榧虞d到轉(zhuǎn)化到代碼需要時(shí)間
2.卡頓優(yōu)化: 2.1 盡量提前計(jì)算好布局,一次性調(diào)整對(duì)應(yīng)屬性避免多次修改
? ? ? ? ? ? ? ? ? ? ? ? 2.2 使用多線程。如果線程開辟太多的話可以結(jié)合信號(hào)量(消耗CPU)
? ? ? ? ? ? ? ? ? ? ? ? 2.3? 數(shù)據(jù)量大的時(shí)候考慮使用本地?cái)?shù)據(jù)(盡量一次性寫入,避免頻繁寫入數(shù)據(jù))
3. 網(wǎng)絡(luò)優(yōu)化:? 1.? E網(wǎng)、4G、WiFi下設(shè)置不同的超時(shí)時(shí)間在用戶體驗(yàn)上顯的比較體驗(yàn)好
? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.?使用后臺(tái)會(huì)話
? ? ? ? ? ? ? ? ? ? ? ? ? ? 3. 使用緩沖減少網(wǎng)絡(luò)請(qǐng)求
4. 耗電優(yōu)化:?一般分為幾個(gè)分為幾個(gè)方面吧 比如網(wǎng)絡(luò)、GPS定位服務(wù)、涉及到硬件方面(藍(lán)牙了 相機(jī)了)等等。
? ? ? ? ? ? ? ? ? ? ? ? ? ? 1.首先是網(wǎng)絡(luò)方面 涉及到視頻、直播之類? 我們知道蜂窩對(duì)電量的消耗遠(yuǎn)遠(yuǎn)大于Wife信號(hào)、因?yàn)樗鞘褂枚鄠€(gè)并發(fā)信號(hào)、并且會(huì)定期的掃描尋找附近更強(qiáng)的信號(hào)、所以我可以做一個(gè)對(duì)于網(wǎng)絡(luò)狀態(tài)的監(jiān)聽? 如過沒wife? 提示用戶是否要播放視頻、直播等等、包括分辨率、音頻考慮是否可以相對(duì)降低。 盡量減少同一操作 使用緩存 定位服務(wù)、藍(lán)牙方面 ? 降低他們的定位或者是發(fā)送/搜索廣播的頻率、當(dāng)用戶進(jìn)入后臺(tái)? 離開特定的頁面 ? 關(guān)閉位置的追蹤和藍(lán)牙功能等等
? ? ? ? ? ? ? ? ? ? ? ? ? 2.涉及到藍(lán)牙 、廣播等等 設(shè)置一個(gè)合理的請(qǐng)求時(shí)間
6.內(nèi)存優(yōu)化: 1. 涉及到通知、定時(shí)器等等釋放的問題
? ? ? ? ? ? ? ? ? ? ? ? 2. tableview. 行高了提前計(jì)算避免多次調(diào)用行高方法,數(shù)據(jù)大分頁顯示
? ? ? ? ? ? ? ? ? ? ? ? 3. 圖片處理,盡量和UIImageView大小相同避免運(yùn)行中縮放,多做緩沖
? ? ? ? ? ? ? ? ? ? ? ? 4.? 大量的臨時(shí)對(duì)象加入Autorelease Pool中執(zhí)行,避免內(nèi)存過高
? ? ? ? ? ? ? ? ? ? ? ? 5.? 數(shù)據(jù)庫的儲(chǔ)存問題
15.? 信號(hào)量
應(yīng)用場(chǎng)景:? 訪問有限的資源、 或者是多線程中的一些特定請(qǐng)求
主要用到的函數(shù):? dispatch_semaphore_create創(chuàng)建信號(hào)量設(shè)置初始值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_semaphore_signal? 發(fā)送信號(hào),信號(hào)量+1
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_semaphore_wait? 等待信號(hào) , 如果大于零則減掉1個(gè)信號(hào)量,往下執(zhí)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 行,如果等于零則阻塞該線程
1. 多個(gè)網(wǎng)絡(luò)請(qǐng)求無序返回后再刷新界面?
? ? ? ? ? ? ? ? ? ? ? ? 創(chuàng)建線程組dispatch_group_create,最后再notify中刷新界面。結(jié)合信號(hào)量使用這樣可? ? ? ? ? ? ? ? ? ? ? ? ? 以保證在沒有所有數(shù)據(jù)返回之前,notify里的內(nèi)容一直不會(huì)執(zhí)行
2.? 多個(gè)網(wǎng)絡(luò)請(qǐng)求有序返回輸出?
? ? ? ? ? 1.信號(hào)量
? ? ? ? ? ? 2. 用NSOPerationQueue中的依賴關(guān)系 [ A? addDependency:B ]
16. 關(guān)于折線圖、柱形、餅狀圖
Chares 圖標(biāo)庫(swift寫的),需要?jiǎng)?chuàng)建一個(gè)橋接,oc-swift
或者是在UIView函數(shù)方法drawRect中自定義貝塞爾曲線 畫柱形設(shè)置(x,y,w,h)? 設(shè)置填充顏色等等
17. AFNetWorking 實(shí)現(xiàn)原理:
? ? ? 主要是用于對(duì)網(wǎng)絡(luò)數(shù)據(jù)的請(qǐng)求和實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)的狀態(tài),由五個(gè)部分組成:
? 1. AFURLSessionManage:核心類,負(fù)責(zé)請(qǐng)求的建立、管理和銷毀等功能
? 2. AFURLRequest:? 請(qǐng)求頭的解碼、序列化、優(yōu)化處理、簡(jiǎn)化拼接過程
? 3. AFURLRepose:? 用于網(wǎng)絡(luò)返回?cái)?shù)據(jù)的處理
4. AFNetWork :? 監(jiān)控網(wǎng)絡(luò)請(qǐng)求的變化
5. UIKit:對(duì)于iOS UIKit的擴(kuò)展庫
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 這里會(huì)常常被問到: AFN網(wǎng)絡(luò)請(qǐng)求的block內(nèi)使用self不會(huì)造成循環(huán)引用?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 答案是:AFNetworking是封裝了一個(gè)completionBlock,AFURLConnectionOperation 里的一個(gè)請(qǐng)求結(jié)束之后,setCompleteBlock會(huì)把block設(shè)置為nil,來打破循環(huán)引用 .
18. 沙河目錄分析:
分為三個(gè)目錄:? Documents、 Library( Caches、Preferences )、 tmp
Documents:保存應(yīng)用運(yùn)行需要持久化的數(shù)據(jù),? sqlite數(shù)據(jù)庫
tmp: 保存運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù)
Library-->Preferences :? NSUserDefaults
19 ?atomic和nonatomic的區(qū)別
1. ? atomic是原子性的(原子性則表示這是一個(gè)不可再分的操作),nonatomic是非原子性的
2. nonatomic和atomic系統(tǒng)自動(dòng)生成的setter和getter方法不一樣,atomic生成的是有加鎖的,而nonatomic是沒有加鎖的(因此,nonatomic的線程不安全,但訪問速度快,而atomic由于加速,訪問速度會(huì)比nonatomic的要慢,但不一定是線程安全的)
3.atomic加鎖只是保證setter和getter的有序性
? ? ? ? ? 比如:線程1調(diào)用了A的setter方法,當(dāng)還沒調(diào)用完時(shí),線程2調(diào)用A的getter方法,但這時(shí)候線程2的調(diào)用要等線程1的完成才能進(jìn)行,但是線程1調(diào)用了getter,線程2調(diào)用了setter,線程3調(diào)用了setter。那么這是后線程1調(diào)用getter后得出的值是不確定的,有可能是線程2操作后的值,也可能是線程3操作后的值?
20. HTTPS 協(xié)議
1.向后臺(tái)開發(fā)者獲取SSL證書(crt格式),并將該文件的格式轉(zhuǎn)換成cer格式
2.? 雙擊該文件,在 keychain (鑰匙串訪問)中找到該文件的證書,項(xiàng)目然后導(dǎo)出cer文件。
3.? AFN 3.0配置? 先導(dǎo)入證書 證書由服務(wù)端生成,使用證書驗(yàn)證模式。 如果是需要驗(yàn)證自建證書,
4. info.plist,配置白名單
22.? runtime面試題
OC的動(dòng)態(tài)性就是由Runtime來支撐和實(shí)現(xiàn)的,Runtime是一套C語言的API,封裝了很多動(dòng)態(tài)性相關(guān)的函數(shù)\平時(shí)編寫的OC代碼,在程序運(yùn)行過程中,其實(shí)最終會(huì)轉(zhuǎn)換成Runtime的C語言代碼,將盡可能多的決策從編譯時(shí)和鏈接時(shí)推遲到運(yùn)行時(shí)
基本作用: 動(dòng)態(tài)的創(chuàng)建類、動(dòng)態(tài)添加修改這個(gè)類的屬性和方法、消息傳遞轉(zhuǎn)發(fā)
說說OC的消息機(jī)制?
1) OC中的方法調(diào)用其實(shí)都是轉(zhuǎn)成了objc_msgSend函數(shù)的調(diào)用,給receiver(方法調(diào)用者)發(fā)送了一條消息(selector方法名)
2)objc_msgSend分為三個(gè)階段(消息發(fā)送、動(dòng)態(tài)方法解析、消息轉(zhuǎn)發(fā))
? ? ? ? ? 2.1消息發(fā)送:
????????????????????? 2.1.1 首先去該類的方法 cache中查找如果找到了就返它 ??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ,????????????????? 2.12、如果沒有找到,就去該類的方法列表中查找。如果在該類的方法列表中找到了,則將 IMP返回
??????????????????? 2.1.3、如果在該類的方法列表中沒找到對(duì)應(yīng)的 IMP,在通過該類結(jié)構(gòu)中的 super_class指針在其父類結(jié)構(gòu)的方法列表中去查找,直到在某個(gè)父類的方法列表中找到對(duì)應(yīng)的IMP,返回它,并加入cache中
?????????????????? 2.14、如果在自身以及所有父類的方法列表中都沒有找到對(duì)應(yīng)的 IMP,則看是不是可以進(jìn)行動(dòng)態(tài)方法解析
? ? ? ? ? 2.2動(dòng)態(tài)方法解析 ( 添加新方法)
? ? ? ? ? ? 如果是 對(duì)象方法調(diào)用會(huì) 調(diào)用_class_resoveInstanceMethod()如果是 類方法調(diào)用 調(diào)用? ? ? ? ? ? ? ? ? ? ? ? ? _class_resoveClassMethod()
? ? ? ? ? 2.3消息轉(zhuǎn)發(fā)? (消息接收者重定向、消息重定向)
????? 消息接收者重定向方法:
? ? ? ? ? ? ? -(id)forwardTargetForSelector:(SEL) aSelector??
? ? ? ? ? ? ? -(void)forwardInvocation:(NSInvocation *)anInvocation
????? 消息重定向:
???????????? -(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; //獲取對(duì)象方法簽名
??????????? -(void)forwardInvocation:(NSInvocation *)anInvocation //對(duì)象方法消息重定向
runtime具體應(yīng)用?
1)分類添加方法 ?。玻┳值滢D(zhuǎn)模型?。常耍郑茫耍郑?Block? ? 4 ) 方法交換?
method swizzling 方法交換原理:? 首先講一下SEL和IMP , SEL 是方法編號(hào)?? IMP是函數(shù)指針地址 ,尋找IMP其實(shí)就是尋找函數(shù)的一個(gè)過程
????????? 每一個(gè)方法都有一個(gè)方法編號(hào)和函數(shù)指針地址,SEL通過對(duì)應(yīng)表去查找IMP
????????? 原理就是 在運(yùn)行時(shí)將一個(gè)方法的實(shí)現(xiàn)替換成另一個(gè)方法實(shí)現(xiàn)的過程! 簡(jiǎn)單來說就是將方法編號(hào)和函數(shù)地址原本對(duì)應(yīng)的關(guān)系斷開,將方法編號(hào)和新的函數(shù)地址進(jìn)行綁定生成新的對(duì)應(yīng)關(guān)系
方法交換需要注意的事項(xiàng):
1> 交換方法應(yīng)當(dāng)在調(diào)用前完成交換,確保在調(diào)用時(shí)已經(jīng)完成交換
2> 交換方法應(yīng)放到dispathc_once中執(zhí)行。防止手動(dòng)調(diào)用+load 方法導(dǎo)致反復(fù)被交換
3> 交換的分類方法應(yīng)該添加自定義前綴,避免沖突(分類的方法會(huì)覆蓋類中同名的方法)
23.? load 和initalize 區(qū)別
load: 在main函數(shù)之前通過函數(shù)內(nèi)存地址調(diào)用。程序啟動(dòng)時(shí)候加載所有的類、每個(gè)類只調(diào)用一次。不需要繼承父類實(shí)現(xiàn)。
initalize: 在main函數(shù)之后通過objc_msgSend收到消息時(shí)調(diào)用。
load和initialize方法都不用顯示的調(diào)用父類的方法而是自動(dòng)調(diào)用,即使子類沒有initialize方法也會(huì)調(diào)用父類的方法,而load方法則不會(huì)調(diào)用父類。
24. 分類不能添加屬性的原因
分類里添加屬性,只是將該屬性添加到該類的屬性列表,并聲明了setter和getter方法,但是沒有生成相應(yīng)的成員變量,也沒有實(shí)現(xiàn)setter和getter方法。所以說分類不能添加屬性 ,如果手動(dòng)實(shí)現(xiàn)的話 改變內(nèi)存的分布情況,這對(duì)編譯性語言是災(zāi)難,是不允許的 。
分類只能擴(kuò)展方法(屬性僅僅是聲明,并沒真正實(shí)現(xiàn))
25 事件的響應(yīng)流程Fr
1.首先通過 hitTest:withEvent: 確定第一響應(yīng)者,以及相應(yīng)的響應(yīng)鏈
2.判斷第一響應(yīng)者能否響應(yīng)事件,如果第一響應(yīng)者能進(jìn)行響應(yīng)則事件在響應(yīng)鏈中的傳遞終止。如果第一響應(yīng)者不能響應(yīng)則將事件傳遞給 nextResponder也就是通常的superview進(jìn)行事件響應(yīng)
3.如果事件繼續(xù)上報(bào)至UIWindow并且無法響應(yīng),它將會(huì)把事件繼續(xù)上報(bào)給UIApplication
4.如果事件繼續(xù)上報(bào)至UIApplication并且也無法響應(yīng),它將會(huì)將事件上報(bào)給其Delegate
5.如果最終事件依舊未被響應(yīng)則會(huì)被系統(tǒng)拋棄
26 單元測(cè)試
介紹: 主要是xcode自帶的XCTest. 簡(jiǎn)單應(yīng)用場(chǎng)景就是(測(cè)試一些功能是否正常、代碼的覆蓋率等等,性能和邏輯的測(cè)試)例如要測(cè)試一個(gè)分享功能,避開重啟APP進(jìn)入分享界面、點(diǎn)擊分享輸入分享內(nèi)容這一些列繁瑣的操作。? 測(cè)試很簡(jiǎn)單、主要是看自己架構(gòu)設(shè)計(jì)
- [ setup ] 測(cè)試用例初始化方法 執(zhí)行之前調(diào)用
- [ textXXX ] 要測(cè)試的實(shí)例方法,以text開頭不含任何參數(shù),測(cè)定預(yù)期值
- [ tearDown ] 清楚測(cè)試方法, 執(zhí)行之后被調(diào)用
邏輯測(cè)試:testLogic 方法 里面? XCTAssertEqual 設(shè)定預(yù)期值驗(yàn)證
性能測(cè)試:testPrefromanceExample 方法? block里面做操作設(shè)置性能值選擇代碼通過率
異步測(cè)試:testAsync方法
UI測(cè)試: 這個(gè)是運(yùn)行程序自動(dòng)生成測(cè)試代碼驗(yàn)證
27 KVC 簡(jiǎn)單分析
分2種: ? setValue: forKey(存值) ? ?和 ?valueForKey(取值)
?setValue: forKey(存值)? ? ?1> ??通過setValue : forKey 方法按照 (setKey 、_setKey)順序查找方法 找到直接傳遞參數(shù)調(diào)用方法
? ? ? ? ? ? ? ? ? ? ? 2> ? 沒找到會(huì)調(diào)用? accessInstanceVariablesDirectly(是否允許查看成員變量)返回值NO 直接調(diào)用valueForUndefinedKey 方法拋出異常
? ? ? ? ? ? ? ? ? ? ? 3> 如果返回YES會(huì)按照(_key 、_isKey 、key 、isKey)查找成員變量 ?找到直接賦值 ?查不到直接拋出異常
?valueForKey(取值) ?1> 通過valueForKey方法按照 (getKey、key、isKey、key) 順序查找方法 找到直接調(diào)用方法
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2>?沒找到會(huì)調(diào)用? accessInstanceVariablesDirectly查看返回值 NO ?直接調(diào)用valueForUndefinedKey 方法拋出異常
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3>?如果返回YES會(huì)按照(_key 、_isKey 、key 、isKey)查找成員變量 ?找到直接賦值 ?查不到直接拋出異常
29 button防止多次點(diǎn)擊
1.? 設(shè)置enabled或userInteractionEnabled屬性
2.? 借助cancelPreviousPerformRequestsWithTarget:selector:object實(shí)現(xiàn)
// 此方法會(huì)在連續(xù)點(diǎn)擊按鈕時(shí)取消之前的點(diǎn)擊事件,從而只執(zhí)行最后一次點(diǎn)擊事件+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;
// 多長(zhǎng)時(shí)間后做某件事情- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
3.? 通過runtime交換方法實(shí)現(xiàn)
? {? ? ? ? ? ?
1 創(chuàng)建一個(gè)UIButton的分類,使用runtime增加public屬性cs_eventInterval和private屬性cs_eventInvalid。? ? ? ? ?
2 在+load方法中使用runtime將UIButton的-sendAction:to:forEvent:方法與自定義的cs_sendAction:to:forEvent:方法進(jìn)行交換? ? ? ? ?
3 使用cs_eventInterval作為控制cs_eventInvalid的計(jì)時(shí)因子,用cs_eventInvalid控制UIButton的event事件是否有效。?
? }
30 WKWebview
WKWebview的白屏的問題:
原因:1. WKWebview是一個(gè)多進(jìn)程組件,內(nèi)存占用太大的時(shí)候會(huì)在加載中奔潰導(dǎo)致白屏。2. 網(wǎng)絡(luò)問題。
解決:1.清理緩沖 重新加載 iOS 9以后 WKNavigtionDelegate 新增了一個(gè)回調(diào)函數(shù)。-(void)webiewXXXTermi nate方法在即將出現(xiàn)白屏的時(shí)候回調(diào)用這個(gè)方法。里面執(zhí)行[webview reload]
WKWebView設(shè)置自定義UserAgent:
? 1. WKWebView的customUserAgent會(huì)覆蓋webview本身的userAgent;2.configuration.applicationNameForUserAgent設(shè)置的userAgent是拼接在webview本身的userAgent后面的。
正確設(shè)置自定義userAgentWKWebViewConfiguration *configuration = [WKWebViewConfiguration new];configuration.applicationNameForUserAgent = "iOS";_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
使用方法:WKWebView來加載網(wǎng)頁,使用WKWebViewConfiguration來配置JS交互。
js調(diào)用OC
1. 主要使用WKUserContentController,用來做 原生與JavaScript的交互管理
2.使用協(xié)議類WKScriptMessageHandler,用來處理監(jiān)聽JavaScript方法從而調(diào)用原生OC方法。
3. 通過 接收J(rèn)S傳出消息的name 進(jìn)行捕捉的回調(diào)方法
OC調(diào)用JS
使用WKUserScript,執(zhí)行自定義的JavaScript代碼
31 MVVM
1.View主要用于界面呈現(xiàn),與用戶輸入設(shè)備進(jìn)行交互
2.ViewModel是MVVM架構(gòu)中最重要的部分,ViewModel中包含屬性,方法,事件,屬性驗(yàn)證等邏輯,負(fù)責(zé)View與Model之間的通訊
3.Model就是我們常說的數(shù)據(jù)模型,用于數(shù)據(jù)的構(gòu)造,數(shù)據(jù)的驅(qū)動(dòng),主要提供基礎(chǔ)實(shí)體的屬性。
MVVM主要目的是分離視圖和模型MVVM優(yōu)點(diǎn):低耦合,可重用性,獨(dú)立開發(fā),可測(cè)試
32 什么時(shí)候會(huì)報(bào)unrecognized selector的異常?
objc在向一個(gè)對(duì)象發(fā)送消息時(shí),runtime庫會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)象實(shí)際所屬的類,然后在該類中的方法列表以及其父類方法列表中尋找方法運(yùn)行,如果,在最頂層的父類中依然找不到相應(yīng)的方法時(shí),會(huì)進(jìn)入消息轉(zhuǎn)發(fā)階段,如果消息三次轉(zhuǎn)發(fā)流程仍未實(shí)現(xiàn),則程序在運(yùn)行時(shí)會(huì)掛掉并拋出異常unrecognized selector sent to XXX 。
33? runtime如何通過selector找到對(duì)應(yīng)的IMP地址?
每一個(gè)類對(duì)象中都一個(gè)方法列表,方法列表中記錄著方法的名稱,方法實(shí)現(xiàn),以及參數(shù)類型,其實(shí)selector本質(zhì)就是方法名稱,通過這個(gè)方法名稱就可以在方法列表中找到對(duì)應(yīng)的方法實(shí)現(xiàn).
34 objc在向一個(gè)對(duì)象發(fā)送消息時(shí),發(fā)生了什么?
objc在向一個(gè)對(duì)象發(fā)送消息時(shí),runtime會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)象實(shí)際所屬的類,然后在該類中的方法列表以及其父類方法列表中尋找方法運(yùn)行,如果一直到根類還沒找到,轉(zhuǎn)向攔截調(diào)用,走消息轉(zhuǎn)發(fā)機(jī)制,一旦找到 ,就去執(zhí)行它的實(shí)現(xiàn)IMP 。
35? AutoreleasePool自動(dòng)釋放池
AutoreleasePool(自動(dòng)釋放池) 是OC中的一種內(nèi)存自動(dòng)回收機(jī)制,在釋放池中的調(diào)用了autorelease方法的對(duì)象都會(huì)被壓在該池的頂部(以棧的形式管理對(duì)象)。當(dāng)自動(dòng)釋放池被銷毀的時(shí)候,在該池中的對(duì)象會(huì)自動(dòng)調(diào)用release方法來釋放資源,銷毀對(duì)象。以此來達(dá)到自動(dòng)管理內(nèi)存的目的
36? APP的啟動(dòng)
按照不同的階段dyld: ??減少動(dòng)態(tài)庫、合并一些動(dòng)態(tài)庫(定期清理不必要的動(dòng)態(tài)庫)減少Objc類、分類的數(shù)量、減少Selector數(shù)量(定期清理不必要的類、分類)減少C++虛函數(shù)數(shù)量Swift盡量使用struct
runtime: 用+initialize方法和dispatch_once取代所有的__attribute__((constructor))、C++靜態(tài)構(gòu)造器、ObjC的+load
main:?在不影響用戶體驗(yàn)的前提下,盡可能將一些操作延遲,不要全部都放在finishLaunching方法中按需加載
4. APP啟動(dòng)優(yōu)化
1.減少數(shù)據(jù)的加載,最好使用懶加載
2.使用多線程技術(shù)加載數(shù)據(jù),充分利用cpu的資源
3.啟動(dòng)時(shí)刻的界面,不要使用storyboard或xib,盡量使用純代碼,因?yàn)閟toryboard或xib有一步代碼轉(zhuǎn)換的操作,也是會(huì)耗時(shí)的
37? @synthesize/@dynamic
@synthesize 表示如果屬性沒有手動(dòng)實(shí)現(xiàn)setter和getter方法,編譯器會(huì)自動(dòng)加上這兩個(gè)方法。@dynamic? 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實(shí)現(xiàn),不自動(dòng)生成。
38 埋點(diǎn)
Flurry: 埋點(diǎn)類——方法列表部署
39 ?GCD
多線程: ??提高CPU資源,實(shí)際往往是將耗時(shí)操作放在后臺(tái)執(zhí)行,避免阻塞主線程,在iOS中UI繪制和用戶響應(yīng)都是主線程
大三類: ? 1> ?NSThread ?使用簡(jiǎn)單 ?缺點(diǎn):?需要自己管理線程的生命周期
? ? ? ? ? ? ? ? ? ? 2>?NSOperation ?不需要關(guān)心線程管理,數(shù)據(jù)同步的事情 對(duì)于GCD的封裝 相比GCD多了一些復(fù)雜功能(線程依賴、最大并發(fā)數(shù)設(shè)置等等)
? ? ? ? ? ? ? ? ? ?3> ?CGD ?用關(guān)心線程代碼的實(shí)現(xiàn), 即不需要關(guān)心什么時(shí)候開起線程, 關(guān)閉線程,只需要?jiǎng)?chuàng)建出來你要執(zhí)行的任務(wù), 然后把任務(wù)添加到適當(dāng)?shù)年?duì)列中(簡(jiǎn)單易用? )
常用線程鎖: 1>?synchronized ?用著更方便,可讀性更高
? ? ? ? ? ? ? ? ? ? ? ? ? 2> NSLock ?必須保證上鎖和開鎖子同一線程 ? 沒有開鎖前再上鎖 會(huì)導(dǎo)致永久性死鎖
? ? ? ? ? ? ? ? ? ? ? ? ? 3>?dispatch_semaphore_t ?只有上一個(gè)執(zhí)行完才繼續(xù)下一個(gè)? 不然一直在等待(dispatch_semaphore_wait)
GCD會(huì)自動(dòng)管理線程的生命周期, 比如創(chuàng)建線程, 調(diào)度任務(wù), 銷毀線程等等操作.
同步執(zhí)行: 在GCD里是sync, 不會(huì)開啟新線程, 只會(huì)在當(dāng)前線程進(jìn)行操作.
異步執(zhí)行: 在GCD里是async, 可以另外開啟一個(gè)新的線程執(zhí)行任務(wù).
并行隊(duì)列: 全名為Concurrent Dispatch Queue, 指的是可以讓多個(gè)任務(wù)同時(shí)執(zhí)行, 如果用到并行隊(duì)列的話, 是會(huì)自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù)
.串行隊(duì)列: 全名Serial Dispatch Queue, 指的是任務(wù)一個(gè)接一個(gè)的執(zhí)行, 完成了前面的那個(gè)就到后面那個(gè), 和我們剛剛舉的收費(fèi)站例子一樣.
使用方法:
這里可以使用dispatch_queue_create來創(chuàng)建對(duì)象, 這里需要傳入兩個(gè)參數(shù)
.第一個(gè)參數(shù): 隊(duì)列的唯一標(biāo)識(shí)符
第二個(gè)參數(shù): 隊(duì)列的類型, DISPATCH_QUEUE_SERIAL表示串行隊(duì)列,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DISPATCH_QUEUE_CONCURRENT表示并行隊(duì)列.
常用方法:
dispatch_after? 設(shè)置延遲在多少秒后執(zhí)行
dispatch_get_global_queue 會(huì)獲取一個(gè)全局隊(duì)列,
dispatch_get_main_queue 會(huì)返回主隊(duì)列
dispatch_once 一次性執(zhí)行 只執(zhí)行一次
40 單例
優(yōu)點(diǎn): 1.不用再頻繁地創(chuàng)建和銷毀對(duì)象,從而提高了系統(tǒng)的性能和節(jié)約系統(tǒng)資源?
? ? ? ? ? ? 2. 單例對(duì)象可以做到按需創(chuàng)建對(duì)象或加載資源,以節(jié)省不必要的內(nèi)存。
缺點(diǎn):? 1. 由于單利模式中沒有抽象層接口,? 單例類很難再進(jìn)行擴(kuò)展
? ? ? ? ? ? 2.單例對(duì)象長(zhǎng)時(shí)間不被利用,系統(tǒng)有可能會(huì)認(rèn)為是垃圾而被回收,這將導(dǎo)致當(dāng)前單例對(duì)象狀態(tài)的丟失。
41 TableView為什么不響應(yīng)touchBegan
通過響應(yīng)鏈我們不難想象到,當(dāng)我們點(diǎn)擊屏幕時(shí),第一響應(yīng)者應(yīng)該是UITableView,而我們調(diào)用的touchBegan其實(shí)是ViewController的View的方法,所以無法被調(diào)用。
UITapGestureRecognizer添加手勢(shì)實(shí)現(xiàn)方法作處理。 ?手勢(shì)方法實(shí)現(xiàn)
/**?? ? 判斷當(dāng)前點(diǎn)擊的位置是否處于 collectionView 對(duì)象內(nèi),如果是,則返回 NO 以使 UITapGestureRecognizer 手勢(shì)對(duì)象失效 ? ?
if ([touch.view isDescendantOfView:self.collectionView]) {
? ? return NO;
? ? }
? ? return YES;
42 加密方式
MD5 ?base64 ? AES ?DES? RSA(RSA (客戶端)公鑰 + 明文 = 密文 —> (服務(wù)器) 私鑰 + 秘文 = 明文)
43? oc中的反射機(jī)制
反射機(jī)制,簡(jiǎn)單的說就是在程序運(yùn)行期間通過類的名字來動(dòng)態(tài)的獲取類的信息,從而實(shí)現(xiàn)動(dòng)態(tài)的創(chuàng)建類,以及動(dòng)態(tài)的調(diào)用類的方法等。
常用到方法: 1> ?isKindOfClass :? 該方法用于判斷一個(gè)對(duì)象是不是一個(gè)類或者這個(gè)類的字類的實(shí)例對(duì)象
???????????????????????? 2> isMemberOfClass :? 該方法用于判斷一個(gè)對(duì)象是不是一個(gè)類的實(shí)例對(duì)象
???????????????????????? 3> respondsToSelector : 該方法用于判斷一個(gè)對(duì)象是否實(shí)現(xiàn)了這個(gè)方法
動(dòng)態(tài)調(diào)用方法: 1、[self performSelector:(id) withObject:(id)];2、objc_msgSend(self,SEL,parameters)等等
44 NSDictionary內(nèi)部實(shí)現(xiàn)
NSDictionary(字典)是使用 hash表來實(shí)現(xiàn)key和value之間的映射和存儲(chǔ)的。hash函數(shù)設(shè)計(jì)的好壞影響著數(shù)據(jù)的查找訪問效率,數(shù)據(jù)在hash表中分布的越均勻,其訪問效率越高。在Objective-C中,通常都是利用NSString 來作為鍵值,其內(nèi)部使用的hash函數(shù)也是通過使用 NSString對(duì)象作為鍵值來保證數(shù)據(jù)的各個(gè)節(jié)點(diǎn)在hash表中均勻分布。在調(diào)用 setObject: forKey: 后,內(nèi)部會(huì)去調(diào)用 key 對(duì)象的 hash 方法確定 object 在hash表內(nèi)的入口位置,然后會(huì)調(diào)用 isEqual 來確定該值是否已經(jīng)存在于 NSDictionary中。
45 NSTimer不準(zhǔn)的問題及解決
原因:???? 1、NSTimer被添加在mainRunLoop中,模式是NSDefaultRunLoopMode,mainRunLoop負(fù)責(zé)所有主線程事件,例如UI界面的操作,復(fù)雜的運(yùn)算,這樣就會(huì)造成timer的阻塞、
????????????? 2、模式的切換,當(dāng)創(chuàng)建的timer被加入到NSDefaultRunLoopMode時(shí),此時(shí)如果有滑動(dòng)UIScrollView的操作,runLoop 的mode會(huì)切換為TrackingRunLoopMode,這是timer會(huì)停止回調(diào)。
解決??? 1、? 在子線程中創(chuàng)建timer,在子線程中進(jìn)行定時(shí)任務(wù)的操作,需要UI操作時(shí)切換回主線程進(jìn)行操作
? ? ? ? ? ? 2、? 使用GCD定時(shí)器、GCD創(chuàng)建的定時(shí)器不受RunLoop中Modes影響 ? ???? dispatch_source_set_timer(GCD dispatch_time_t 里面的都是納秒)
46 內(nèi)存管理
?MRC: 手動(dòng)管理內(nèi)存(人工引用計(jì)數(shù))當(dāng)引用計(jì)數(shù)為0的時(shí)候,必須回收 ? 繼續(xù)釋放,會(huì)造成野指針,為了避免出現(xiàn)野指針
ARC:自動(dòng)管理內(nèi)存(自動(dòng)引用計(jì)數(shù)) ??只要沒有強(qiáng)指針(強(qiáng)引用)指向?qū)ο?,?duì)象就會(huì)被釋放
ARC下需要注意: 循環(huán)引用問題(block 使用__weakSelf 代替self 、 代理使用weak 修飾屬性)涉及到定時(shí)器、通知、單利等需要手動(dòng)釋放避免內(nèi)存泄漏
一般會(huì)影響性能 ?嚴(yán)重導(dǎo)致程序崩潰 ???一般使用Xcode自帶的Instruments工具中的leaks檢測(cè) ? 標(biāo)紅的表示可能存在泄漏問題 ? 查看具體解決
47 簡(jiǎn)單排序思路
快速排序: ? ? 通過一趟排序?qū)?shù)據(jù)分割成兩部分,其中一部分的所有數(shù)據(jù)都比另一部分的所有數(shù)據(jù)都小,但是兩部分?jǐn)?shù)據(jù)是無序的。然后再對(duì)兩部分的數(shù)據(jù)分別進(jìn)行第一趟的排序,直到最后的數(shù)據(jù)是有序的每次交換是跳躍式的。每次排序的時(shí)候設(shè)置一個(gè)基準(zhǔn)點(diǎn),將小于等于基準(zhǔn)點(diǎn)的數(shù)全部放到基準(zhǔn)點(diǎn)的左邊,將大于等于基準(zhǔn)點(diǎn)的數(shù)全部放到基準(zhǔn)點(diǎn)的右邊。
選擇排序: 是一種簡(jiǎn)單直觀的排序算法。它的工作原理是每一次從待排序的數(shù)據(jù)元素中選出最?。ɑ蜃畲螅┑囊粋€(gè)元素,存放在序列的起始位置,然后,再從剩余未排序元素中繼續(xù)尋找最?。ù螅┰?,然后放到已排序序列的末尾
48 崩潰異常處理
一般使用三方Bugly、AvoidCrash
這個(gè)三方可以處理例如插入空值到字典中或數(shù)組中引起的崩潰、數(shù)組越界引起的崩潰、unrecognized selector sent to instance等等的崩潰,都能捕獲并且避免閃退
也可以在它異常處理的方法下 選擇上傳服務(wù)器 ?對(duì)于線上出現(xiàn)的閃退 異??梢赃M(jìn)行定位處理