1、有些圖片加載的比較慢怎么處理?怎么優(yōu)化性能?
圖片下載放在異步線程
圖片下載過(guò)程中使用占位圖片
如果圖片較大,可以考慮多線程斷點(diǎn)下載
2、單例是怎么實(shí)現(xiàn)的
說(shuō)白了就是一個(gè)類不通過(guò)alloc方式創(chuàng)建對(duì)象,而是用一個(gè)靜態(tài)方法返回這個(gè)類的對(duì)象。系統(tǒng)只需要擁有一個(gè)的 全局對(duì)象,這樣有利于我們協(xié)調(diào)系統(tǒng)整體的行為;
具體代碼怎么寫(xiě):dispath_once
怎么保障變量到這只執(zhí)行一次:dispath_once
只保存一份內(nèi)存地址:用static修飾變量
static的作用:全局的變量只初始化一次,把變量保存在靜態(tài)分區(qū)中,程序從開(kāi)始運(yùn)行到結(jié)束變量只有一份內(nèi)存地址
3、代理
自己用的不多,UITableView、UICollectionView這里都用到。把某個(gè)對(duì)象要做的事情委托給別的對(duì)象去做。那么別的對(duì)象就是這個(gè)對(duì)象的代理,代替它來(lái)打理要做的事。反映到程序中,首先要明確一個(gè)對(duì)象的委托方是哪個(gè)對(duì)象,委托所做的內(nèi)容是什么。常見(jiàn)的如QQ的自動(dòng)回復(fù)就屬于代 理攔截,代理模式在iphone中得到廣泛應(yīng)用。
4、用的架構(gòu)是什么模式?MVC三者之間是怎樣相互通信的,V和C通過(guò)什么傳遞?
MVC是一種架構(gòu)模式,M表示MOdel,V表示視圖View,C表示控制器Controller,Model負(fù)責(zé)存儲(chǔ)、定義、操作數(shù)據(jù),View用來(lái)展示書(shū)給用戶,和用戶進(jìn)行操作交互,Controller是Model和View的協(xié)調(diào)者,Controller把Model中的數(shù)據(jù)拿過(guò)來(lái)給View用。Controller可以直接與Model和View進(jìn)行通信,而View不能和Controller直接通信。View與Controller通信需要利用代理協(xié)議的方式,Controller遵守代理,實(shí)現(xiàn)代理的方法,來(lái)監(jiān)聽(tīng)View的事件。當(dāng)有數(shù)據(jù)更新時(shí),Model也要與Controller進(jìn)行通信,這個(gè)時(shí)候就要用Notification和KVO,這個(gè)方式就像一個(gè)廣播一樣,Model發(fā)信號(hào),Controller設(shè)置監(jiān)聽(tīng)接受信號(hào),當(dāng)有數(shù)據(jù)更新時(shí)就發(fā)信號(hào)給Controller,Model和View不能直接進(jìn)行通信,這樣會(huì)違背MVC設(shè)計(jì)模式。
5、對(duì)觀察者模式的理解
Notification 是觀察者模式的實(shí)現(xiàn),KVO是觀察者模式的OB-C底層實(shí)現(xiàn)。
NOtification 通過(guò) Notifydcation addobserver 和 remove observer 工作。當(dāng)一個(gè)物體發(fā)生變化時(shí),會(huì)通知所有觀察這個(gè)物體的觀察者讓其做出反應(yīng)。實(shí)現(xiàn)起來(lái)無(wú)非就是把所有觀察者的 對(duì)象給這個(gè)物體,當(dāng)這個(gè)物體的發(fā)生改變,就會(huì)調(diào)用遍歷所有觀察者的對(duì)象調(diào)用觀察者的方法從而達(dá)到通知觀察者的目的。
KVO(Key-Value- Observing) 是鍵值監(jiān)聽(tīng),鍵值觀察機(jī)制,提供了觀察某一屬性變化的方法,底層實(shí)現(xiàn):當(dāng)觀察者為一個(gè)對(duì)象的屬性進(jìn)行了注冊(cè),被觀察對(duì)象的isa指針被修改的時(shí)候,isa指針就會(huì)指向一個(gè)中間類,而不是真實(shí)的類。所以 isa指針其實(shí)不需要指向?qū)嵗龑?duì)象真實(shí)的類。所以我們的程序最好不要依賴于isa指針。在調(diào)用類的方法的時(shí)候,最好要明確對(duì)象實(shí)例的類名
KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):KVC是鍵值編碼,是一種間接訪問(wèn)對(duì)象的屬性,使用字符串來(lái)標(biāo)示屬性(例如:setValue:forKey:) ,一個(gè)對(duì)象在調(diào)setValue的時(shí)候,(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán)境參數(shù)。(2)他會(huì)從 isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。(3)再直接查找得來(lái)的具體的方法實(shí)現(xiàn)。
6、代理和通知的區(qū)別
通知是一對(duì)多,代理是一對(duì)一
1、效率肯定是delegate比NSNotification高。
2、delegate方法比notification更加直接,需要關(guān)注返回值,所以delegate方法往往包含should這個(gè)很傳神的詞。相反的,notification最大的特色就是不關(guān)心結(jié)果。所以notification往往用did這個(gè)詞匯。
3、兩個(gè)模塊之間聯(lián)系不是很緊密,就用notification傳值,例如多線程之間傳值用notificaiton。
4、delegate只是一種較為簡(jiǎn)單的回調(diào),且主要用在一個(gè)模塊中,例如底層功能完成了,需要把一些值傳到上層去,就事先把上層的函數(shù)通過(guò)delegate傳到底層,然后在底層call這個(gè)delegate,它們都在一個(gè)模塊中,完成一個(gè)功能,例如說(shuō) NavgationController 從 B 界面到A 點(diǎn)返回按鈕 (調(diào)用popViewController方法) 可以用delegate比較好。
7、第三方框架 MapKit
MapKit蘋(píng)果原生框架
8、微信支付和支付寶支付的區(qū)別
9、多線程N(yùn)SOperation GCD區(qū)別
項(xiàng)目中使用NSOperation的優(yōu)點(diǎn)是NSOperation是對(duì)線程的高度抽象,在項(xiàng)目中使用它,會(huì)使項(xiàng)目的程序結(jié)構(gòu)更好,子類化NSOperation的設(shè)計(jì)思路,是具有面向?qū)ο蟮膬?yōu)點(diǎn)(復(fù)用、封裝),使得實(shí)現(xiàn)是多線程支持,而接口簡(jiǎn)單,建議在復(fù)雜項(xiàng)目中使用。項(xiàng)目中使用GCD的優(yōu)點(diǎn)是GCD本身非常簡(jiǎn)單、易用,對(duì)于不復(fù)雜的多線程操作,會(huì)節(jié)省代碼量,而B(niǎo)lock參數(shù)的使用,會(huì)是代碼更為易讀,建議在簡(jiǎn)單項(xiàng)目中使用。
10、block,block在哪種情況下會(huì)造成循環(huán)引用,如何解決?
(1) block本質(zhì)是一個(gè)數(shù)據(jù)類型,多用于參數(shù)傳遞,代替代理方法, (有多個(gè)參數(shù)需要傳遞或者多個(gè)代理方法需要實(shí)現(xiàn)還是推薦使用代理方法),少用于當(dāng)做返回值傳遞. block是一個(gè)OC對(duì)象,它的功能是保存代碼片段,預(yù)先準(zhǔn)備好代碼,并在需要的時(shí)候執(zhí)行.
(2)因?yàn)槭褂胋lock代碼塊可能會(huì)引起內(nèi)部循壞引用,所以應(yīng)在block定義前加上修飾
(1)從兩方面分析造成循環(huán)引用問(wèn)題
當(dāng)self擁有一個(gè)block的時(shí)候,在block又調(diào)用self的方法(或者self所擁有的某個(gè)屬性)。形成你中有我,我中有你,這種時(shí)候會(huì)造成循環(huán)引用 (你擁有一個(gè)對(duì)象包含了另外了一個(gè)實(shí)例變量對(duì)象,但是第二個(gè)對(duì)象又把前一個(gè)對(duì)象作為它的委托,那么這兩個(gè)對(duì)象將不會(huì)被釋放。)
把某個(gè)實(shí)例變量變成本地臨時(shí)變量,強(qiáng)引用將直接指向這個(gè)本地臨時(shí)變量,但本地臨時(shí)變量一般都會(huì)很快釋放,所以一般考慮第一種情況
(2)解決方案:對(duì)block進(jìn)行修飾__weak(arc)或__block(mrc)
11、屬性修飾符copy、strong區(qū)別
OC中NSString為不可變字符串的時(shí)候,用copy和strong都是只分配一次內(nèi)存,但是如果用copy的時(shí)候,需要先判斷字符串是否不可變字符串,如果是不可變字符串,就不再分配空間,如果是可變字符串才分配空間。如果程序中用到NSString的地方特別的,每一次都要先進(jìn)行判斷就會(huì)消耗性能,影響用戶體驗(yàn),用strong就不會(huì)再進(jìn)行判斷,所以,不可變字符串可以直接用strong。
屬性修飾符weak、strong區(qū)別
weak :弱引用 ,ARC中使用,如果只想的對(duì)象被釋放了,其指向nil,可以有效的避免野指針,其引用計(jì)數(shù)為1。
strong :強(qiáng)引用,ARC中使用,與MRC中retain類似,使用之后,計(jì)數(shù)器+1。
(weak和strong)不同的是 當(dāng)一個(gè)對(duì)象不再有strong類型的指針指向它的時(shí)候 它會(huì)被釋放 ,即使還有weak型指針指向它。
一旦最后一個(gè)strong型指針離去 ,這個(gè)對(duì)象將被釋放,所有剩余的weak型指針都將被清除。
可能有個(gè)例子形容是妥當(dāng)?shù)摹?br>
想象我們的對(duì)象是一條狗,狗想要跑掉(被釋放)。
strong型指針就像是栓住的狗。只要你用牽繩掛住狗,狗就不會(huì)跑掉。如果有5個(gè)人牽著一條狗(5個(gè)strong型指針指向1個(gè)對(duì)象),除非5個(gè)牽繩都脫落 ,否著狗是不會(huì)跑掉的。
weak型指針就像是一個(gè)小孩指著狗喊到:“看!一只狗在那” 只要狗一直被栓著,小孩就能看到狗,(weak指針)會(huì)一直指向它。只要狗的牽繩脫落,狗就會(huì)跑掉,不管有多少小孩在看著它。
只要最后一個(gè)strong型指針不再指向?qū)ο?,那么?duì)象就會(huì)被釋放,同時(shí)所有的weak型指針都將會(huì)被清除。
弱引用用在哪里
用在block和delegate中
當(dāng)self擁有一個(gè)block的時(shí)候,在block又調(diào)用self的方法(或者self所擁有的某個(gè)屬性)。形成你中有我,我中有你,這種時(shí)候會(huì)造成循環(huán)引用。
你擁有一個(gè)對(duì)象包含了另外了一個(gè)實(shí)例變量對(duì)象,但是第二個(gè)對(duì)象又把前一個(gè)對(duì)象作為它的委托,那么這兩個(gè)對(duì)象將不會(huì)被釋放。
變量是弱引用的話只能用__weak修飾嗎?還有什么
修飾delegate,即定義一個(gè)delegate的屬性時(shí),還可以使用__unsafe_unretain和__weak來(lái)修飾,然后通過(guò)使用__unsafe_unretain和__weak來(lái)單獨(dú)標(biāo)記實(shí)例變量。這意味著delegate實(shí)例變量將仍然能夠指向第一個(gè)對(duì)象,但是它不會(huì)導(dǎo)致保留第一個(gè)對(duì)象,因此打破了retain cycle,而能夠釋放兩個(gè)對(duì)象。
__unsafe_unretain和__weak都能避免retain cycle,但是他們也有一些細(xì)微的不同。對(duì)于__weak,當(dāng)釋放指針指向的對(duì)象時(shí),該對(duì)象的指針將轉(zhuǎn)換為nil,這是比較安全的行為。而__unsafe_unretain,正如其名稱隱藏的含義,盡管釋放指針指向的對(duì)象時(shí),該指針將繼續(xù)指向原來(lái)的內(nèi)存。這將會(huì)導(dǎo)致應(yīng)用crash,所以是unsafe。
為什么我們?nèi)砸褂胈_unsafe_unretain呢?這是因?yàn)開(kāi)_weak直到iOS5.0以及l(fā)ion之后才出現(xiàn)。
12、數(shù)據(jù)存儲(chǔ)
四種存儲(chǔ)方式: 1.NSUserDefaults,用于存儲(chǔ)配置信息;2.SQLite,用于存儲(chǔ)查詢需求較多的數(shù)據(jù);3.CoreData,用于規(guī)劃應(yīng)用中的對(duì)象;4.使用基本對(duì)象類型定制的個(gè)性化緩存方案.
NSUserDefaults:對(duì)象中儲(chǔ)存了系統(tǒng)中用戶的配置信息,開(kāi)發(fā)者可以通過(guò)這個(gè)實(shí)例對(duì)象對(duì)這些已有的信息進(jìn)行修改,也可以按照自己的需求創(chuàng)建新的配置項(xiàng)。
SQLite擅長(zhǎng)處理的數(shù)據(jù)類型其實(shí)與NSUserDefaults差不多,也是基礎(chǔ)類型的小數(shù)據(jù),只是從組織形式上不同。開(kāi)發(fā)者可 以以關(guān)系型數(shù)據(jù)庫(kù)的方式組織數(shù)據(jù),使用SQL DML來(lái)管理數(shù)據(jù)。一般來(lái)說(shuō)應(yīng)用中的格式化的文本類數(shù)據(jù)可以存放在數(shù)據(jù)庫(kù) 中,尤其是類似聊天記錄、Timeline等這些具有條件查詢和排序需求的數(shù)據(jù)。
CoreData是一個(gè)管理方案,它的持久化可以通過(guò)SQLite、XML或二進(jìn)制文件儲(chǔ)存。它可以把整個(gè)應(yīng)用中的對(duì)象建模并進(jìn) 行自動(dòng)化的管理。從歸檔文件還原模型時(shí)CoreData并不是一次性把整個(gè)模型中的所有數(shù)據(jù)都載入內(nèi)存,而是根據(jù)運(yùn)行時(shí)狀態(tài),把被調(diào)用到的對(duì)象實(shí)例載入內(nèi)存??蚣軙?huì)自動(dòng)控制這個(gè)過(guò)程,從而達(dá)到控制內(nèi)存消耗,避免浪費(fèi)。 無(wú)論從設(shè)計(jì)原理還是使用方法上看,CoreData都比較復(fù)雜。因此,如果僅僅是考慮緩存數(shù)據(jù)這個(gè)需求,CoreData絕對(duì)不 是一個(gè)優(yōu)選方案。CoreData的使用場(chǎng)景在于:整個(gè)應(yīng)用使用CoreData規(guī)劃,把應(yīng)用內(nèi)的數(shù)據(jù)通過(guò)CoreData建模,完全 基于CoreData架構(gòu)應(yīng)用。 使用基本對(duì)象類型定制的個(gè)性化緩存方案:從需求出發(fā)分析緩存數(shù)據(jù)有哪些要求:按Key查找,快速讀取,寫(xiě)入不影響正常 操作,不浪費(fèi)內(nèi)存,支持歸檔。這些都是基本需求,那么再進(jìn)一步或許還需要固定緩存項(xiàng)數(shù)量,支持隊(duì)列緩存,緩存過(guò)期 等。
13、CALayer層和UIView的關(guān)系
UIView和CALayer是相互依賴的關(guān)系。UIView依賴與calayer提供的內(nèi)容,CALayer依賴uivew提供的容器來(lái)顯示繪制的內(nèi)容。歸根到底CALayer是這一切的基礎(chǔ),如果沒(méi)有CALayer,UIView自身也不會(huì)存在,UIView是一個(gè)特殊的CALayer實(shí)現(xiàn),添加了響應(yīng)事件的能力。UIView來(lái)自CALayer,高于CALayer,是CALayer高層實(shí)現(xiàn)與封裝。UIView的所有特性來(lái)源于CALayer支持。
14、代碼管理工具git
Git是什么:Git是目前世界上最先進(jìn)的分布式版本控制系統(tǒng)(沒(méi)有之一)。
什么是版本控制系統(tǒng):版本控制是一種記錄一個(gè)或若干文件內(nèi)容變化,以便將來(lái)查閱特定版本修訂情況的系統(tǒng)
集中式 vs分布式
CVS及SVN都是集中式的版本控制系統(tǒng),而Git是分布式版本控制系統(tǒng)。
集中式和分布式版本控制系統(tǒng)有什么區(qū)別呢?
集中式版本控制系統(tǒng):版本庫(kù)是集中存放在中央服務(wù)器的,而干活的時(shí)候,用的都是自己的電腦,所以要先從中央服務(wù)器取得最新的版本,每個(gè)人電腦上都有一個(gè)完整的版本庫(kù)然后開(kāi)始干活,干完活了,再把自己的活推送給中央服務(wù)器。
分布式版本控制系統(tǒng):每個(gè)人的電腦里有完整的版本庫(kù),統(tǒng)通常也有一臺(tái)充當(dāng)“中央服務(wù)器”的電腦,但這個(gè)服務(wù)器的作用僅僅是用來(lái)方便“交換”大家的修改,沒(méi)有它大家也一樣干活,只是交換修改不方便而已。
15、什么是分支,怎樣創(chuàng)建分支
終端$ git branch testing
我們知道每次我們commit的時(shí)候都會(huì)生成一個(gè)快照,或者說(shuō)一個(gè)版本庫(kù),從引言我們也知道了通過(guò)Blob對(duì)象存儲(chǔ)文件快照內(nèi)容,然后Tree對(duì)象記錄快照索引目錄,通過(guò)索引找到文件快照。
16、runtiem、runloop的實(shí)現(xiàn)機(jī)制
Runtime:runtime是一套比較底層的純C語(yǔ)言API,屬于1個(gè)C語(yǔ)言庫(kù),包含了很多底層的C語(yǔ)言API。在我們平時(shí)編寫(xiě)的OC代碼中,程序運(yùn)行過(guò)程時(shí),其實(shí)最終都是轉(zhuǎn)成了runtime的C語(yǔ)言代碼, runtime算是OC的幕后工作者.
NSRunLoop是iOS的消息機(jī)制的處理模式
1、NSRunloop的主要作用:控制runloop里面線程的執(zhí)行和休眠,在有事情做的時(shí)候使擋墻NSRunloop控制的線程工作,沒(méi)有事情做讓當(dāng)前runloop的控制線程休眠.
2、runloop就是一直在循環(huán)檢測(cè),從線程start到線程end,檢測(cè)inputsourse(如點(diǎn)擊,雙擊等操作)異步時(shí)間,檢測(cè)timesourse同步事件,見(jiàn)到檢測(cè)到輸入源會(huì)執(zhí)行處理函數(shù),首先會(huì)產(chǎn)生通知,corefunction向線程添加runloop observers來(lái)監(jiān)聽(tīng)事件,意在監(jiān)聽(tīng)事件發(fā)生時(shí)來(lái)做處理。
3、runloopmode是一個(gè)集合,包括監(jiān)聽(tīng):事件源,定時(shí)器,以及需通知的runloop observers
runloop在多線程中如何使用
1、只有在為你的程序創(chuàng)建次線程的時(shí)候,才需要運(yùn)行run loop。對(duì)于程序的主線程而言,run loop是關(guān)鍵部分。Cocoa提供了運(yùn)行主線程run loop的代碼同時(shí)也會(huì)自動(dòng)運(yùn)行run loop。IOS程序UIApplication中的run方法在程序正常啟動(dòng)的時(shí)候就會(huì)啟動(dòng)run loop。如果你使用xcode提供的模板創(chuàng)建的程序,那你永遠(yuǎn)不需要自己去啟動(dòng)run loop
2、在多線程中,你需要判斷是否需要run loop。如果需要run loop,那么你要負(fù)責(zé)配置run loop并啟動(dòng)。你不需要在任何情況下都去啟動(dòng)run loop。比如,你使用線程去處理一個(gè)預(yù)先定義好的耗時(shí)極長(zhǎng)的任務(wù)時(shí),你就可以毋需啟動(dòng)run loop。Run loop只在你要和線程有交互時(shí)才需要
17、自動(dòng)釋放池,如何工作
自動(dòng)釋放池以棧的形式實(shí)現(xiàn):當(dāng)你創(chuàng)建一個(gè)新的自動(dòng)釋放池時(shí),它將被添加到棧頂.當(dāng)一個(gè)對(duì)象收到發(fā)送autorelease消息時(shí),他被添加到當(dāng)前線程的處于棧頂?shù)淖詣?dòng)釋放池中,當(dāng)自動(dòng)釋放池被回收時(shí),他們從棧中被刪除,并且會(huì)給池子里面所有的對(duì)象都會(huì)做一次release操作。1. ojc-c是通過(guò)種"referringcounting"(引計(jì)數(shù))的方式來(lái)管理內(nèi)存的, 對(duì)象在開(kāi)始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一,以后每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷毀.
- NSAutoreleasePool 就是用來(lái)做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不你管的.
- autorelease和release沒(méi)什么區(qū)別,只是引計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引計(jì)數(shù)減一.
18、http和scoket通信的區(qū)別?socket連接相關(guān)庫(kù),TCP,UDP的連接方法,HTTP的幾種常用方式?
http和scoket通信的區(qū)別: http是客戶端用http協(xié)議進(jìn)行請(qǐng)求,發(fā)送請(qǐng)求時(shí)候需要封裝http請(qǐng)求頭,并綁定請(qǐng)求的數(shù)據(jù),服務(wù)器一般有web服務(wù)器配 合(當(dāng)然也非絕對(duì))。 http請(qǐng)求方式為客戶端主動(dòng)發(fā)起請(qǐng)求,服務(wù)器才能給響應(yīng),一次請(qǐng)求完畢后則斷開(kāi)連接,以節(jié)省資 源。服務(wù)器不能主動(dòng)給客戶端響應(yīng)(除非采取http長(zhǎng)連接技術(shù))。iphone主要使用類是NSUrlConnection。 scoket是客戶端跟服務(wù)器直接使用socket“套接字”進(jìn)行連接,并沒(méi)有規(guī)定連接后斷開(kāi),所以客戶端和服務(wù)器可以保持連 接通道,雙方都可以主動(dòng)發(fā)送數(shù)據(jù)。一般在游戲開(kāi)發(fā)或股票開(kāi)發(fā)這種要求即時(shí)性很強(qiáng)并且保持發(fā)送數(shù)據(jù)量比較大的場(chǎng)合使 用。主要使用類是CFSocketRef。
UDP:是用戶數(shù)據(jù)報(bào)協(xié)議:主要用在實(shí)時(shí)性要求高以及對(duì)質(zhì)量相對(duì)較弱的地方,但面對(duì)現(xiàn)在高質(zhì)量的線路不是容易丟包除非 是一些擁塞條件下 ,如流媒體
TCP:是傳輸控制協(xié)議:是面連接的,那么運(yùn)行環(huán)境必然要求其可靠性不可丟包有良好的擁塞控制機(jī)制如http ftp telnet 等
http的常用方式:get,post