之前看了這邊文章面試經(jīng)歷 自己整理的面試答案
1朽褪、說一下OC的反射機(jī)制
在動態(tài)運(yùn)行下我們可以構(gòu)建任何一個類,然后我們通過這個類知道這個類的所有的屬性和方法友题,并且如果我們創(chuàng)建一個對象戴质,我們也可以通過對象找到這個類的任意一個方法告匠,這就是反射機(jī)制后专。
比如NSClassFormString戚哎,NSStringFormSelector型凳,NSSelectorFormString
參考鏈接
2啰脚、block的本質(zhì)是什么橄浓?有幾種block荸实?分別是怎樣產(chǎn)生的泄朴?
參考鏈接
block與函數(shù)類似祖灰,只不過是直接定義在另一個函數(shù)里局扶,和定義它的那個函數(shù)共享同一個范圍內(nèi)的東西三妈,
block的強(qiáng)大之處是:在聲明它的范圍里悠鞍,所有變量都可以為其捕獲咖祭,這也就是說涧窒,那個范圍內(nèi)的全部變量硬鞍,在block依然可以用戴已,默認(rèn)情況下,為block捕獲的變量伐坏,是不可以在block里修改的桦沉,不過聲明的時候可以加上__block修飾符纯露,這樣就可以再block內(nèi)修改了埠褪。
block本身和其他對象一樣钞速,有引用計(jì)數(shù),當(dāng)最后一個指向block的引用移走之后嫡秕,block就回收了渴语,回收時也釋放block所捕獲的變量。
Block的實(shí)現(xiàn)是通過結(jié)構(gòu)體的方式實(shí)現(xiàn)昆咽,在編譯的過程中驾凶,將Block生成對應(yīng)的結(jié)構(gòu)體屠升,在結(jié)構(gòu)體中記錄Block的匿名函數(shù),以及使用到的自動變量狭郑,在最后的使用中翰萨,通過Block結(jié)構(gòu)體實(shí)例訪問成員中存放的匿名函數(shù)地址調(diào)用匿名函數(shù),并將自身作為參數(shù)傳遞。
block其實(shí)就是C語言的擴(kuò)充功能,實(shí)現(xiàn)了對C的閉包實(shí)現(xiàn)辛蚊,一個帶有局部變量的匿名函數(shù)虑凛,
block的本質(zhì)也是一個OC對象焰宣,它內(nèi)部也有一個isa指針,block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對象,為了保證block內(nèi)部能夠正常訪問外部的變量础浮,block有一個變量捕獲機(jī)制含鳞。static 修飾的變量為指針傳遞熔吗,同樣會被block捕獲。局部變量因?yàn)榭绾瘮?shù)訪問所以需要捕獲,全局變量在哪里都可以訪問 吱型,所以不用捕獲灼伤。
當(dāng)block內(nèi)部訪問了對象類型的auto變量時颖侄,如果block在棧上,block內(nèi)部不會對變量產(chǎn)生強(qiáng)應(yīng)用苔咪,不論block的結(jié)構(gòu)體內(nèi)部的變量時__strong修飾還是__weak修飾耐薯,都不會對變量產(chǎn)生強(qiáng)引用
默認(rèn)情況下block不能修改外部的局部變量
1.static修飾
static修飾的age變量傳遞到block內(nèi)部的是指針复斥,在__main_block_func_0函數(shù)內(nèi)部就可以拿到age變量的內(nèi)存地址痢虹,因此就可以在block內(nèi)部修改age的值丰捷。
有三種類型
__NSGlobalBlock__ ( _NSConcreteGlobalBlock )
__NSStackBlock__ ( _NSConcreteStackBlock )
__NSMallocBlock__ ( _NSConcreteMallocBlock )
__block內(nèi)存管理
當(dāng)block內(nèi)存在棧上時,并不會對__block變量產(chǎn)生內(nèi)存管理,當(dāng)block被copy到堆上時會調(diào)用block內(nèi)部的copy函數(shù),copy函數(shù)內(nèi)部會滴啊用_Block_object_assign函數(shù)渗磅,_Block_object_assign函數(shù)會對__block變量形成強(qiáng)引用(相當(dāng)于retain)。
當(dāng)block被copy到堆上時,block內(nèi)部引用的__block變量也會被復(fù)制到堆上纸厉,并且持有變量则吟,如果block復(fù)制到堆上的同時,__block變量已經(jīng)存在堆上了,則不會復(fù)制炼七。
當(dāng)block從堆中移除的話捉超,就會調(diào)用dispose函數(shù),也就是__main_block_dispose_0函數(shù)祠够,__main_block_dispose_0函數(shù)內(nèi)部會調(diào)用_Block_object_dispose函數(shù),會自動釋放引用的__block變量痛侍。
解決循環(huán)引用問題
使用__weak和__unsafe_unretained修飾符合一解決循環(huán)引用的問題将宪,__weak會使block內(nèi)部將指針變?yōu)槿踔羔槨?br>
__weak 和 __unsafe_unretained的區(qū)別。
__weak不會產(chǎn)生強(qiáng)引用,指向的對象銷毀時泛豪,會自動將指針置為nil
__unsafe_unretained不會產(chǎn)生強(qiáng)引用劝萤,不安全,指向的對象銷毀時捷绒,指針存儲的地址值不變
__strong 和 __weak
在block內(nèi)部重新使用__strong修飾self變量是為了在block內(nèi)部有一個強(qiáng)指針指向weakSelf避免在block調(diào)用的時候weakSelf已經(jīng)被銷毀函荣。
2.__block修飾的變量為什么能在block里面能改變其值扳肛?
__block用于解決block內(nèi)部不能修改auto變量值的問題,__block不能修飾靜態(tài)變量和全局變量
_block 所起到的作用就是只要觀察到該變量被 block 所持有,就將“外部變量”在棧中的內(nèi)存地址放到了堆中。進(jìn)而在block內(nèi)部也可以修改外部變量的值闹啦。
3.NSDictionary使用原理
NSDictionary是使用hash表來實(shí)現(xiàn)key和vaLue之間的映射和存儲的
hash原理
hash概念:哈希表的本質(zhì)是一個數(shù)組吁峻,數(shù)組中沒一個元素稱為一個箱子,箱子中存放的是鍵值對蛇尚。
哈希表的存儲過程:
1.根據(jù)key計(jì)算出它的哈希值h
2.假設(shè)箱子的個數(shù)為n芽唇,那么這個鍵值對應(yīng)應(yīng)該在第(h % n)個箱子中。
3.如果該箱子中已經(jīng)有了鍵值對,就使用開放尋址法或者拉鏈法解決沖突匆笤。
在使用拉鏈法解決哈希沖突時研侣,每個箱子其實(shí)是一個鏈表,屬于同一個箱子的所有鍵值對都會排列在鏈表中炮捧。
哈希表還有一個重要的屬性:負(fù)載因子(load factor)庶诡,它用來衡量哈希表的空/滿程度,一定程度上也可以體現(xiàn)查詢的效率咆课,計(jì)算公式為:
4.NSCache優(yōu)于NSDictionary的幾點(diǎn)末誓?
NSCache是一個容器,類似于NSDictionary,通過key-value形式存儲和查詢值傀蚌,用于臨時存儲對象基显。
NSCache勝過NSDictionary之處在于,當(dāng)系統(tǒng)資源將要耗盡時善炫,它可以自動刪減緩存撩幽。如果采用普通的字典,那么就要自己編寫掛鉤箩艺,在系統(tǒng)發(fā)出“低內(nèi)存”通知時手工刪減緩存窜醉。
NSCache并不會“拷貝”鍵,而是會“保留”它艺谆。此行為用NSDictionary也可以實(shí)現(xiàn)榨惰,然而需要編寫相當(dāng)復(fù)雜的代碼。NSCache對象不拷貝鍵的原因在于:很多時候静汤,鍵都是不支持拷貝操作的對象來充當(dāng)?shù)睦糯摺R虼耍琋SCache不會自動拷貝鍵虫给,所以說藤抡,在鍵不支持拷貝操作的情況下,該類用起來比字典更方便抹估。另外缠黍,NSCache是線程安全的,而NSDictionary則絕對不具備此優(yōu)勢药蜻。
5.屬性
屬性是OC的一項(xiàng)特性瓷式,用于封裝對象的數(shù)據(jù),OC對象通常會把其所需要的數(shù)據(jù)保存為各種實(shí)例對象语泽,實(shí)例對象一般通過存取方法來訪問贸典,其中獲取方法用于讀取變量值,而設(shè)置方法用于寫入變量值踱卵,開發(fā)者可以令編譯器自動編寫與屬性相關(guān)的存取方法瓤漏。
6.理解objc_msgSend的作用
objc_msgSend叫做消息傳遞,消息有名稱或選擇子,可以接受參數(shù)
Runtime時執(zhí)行的流程是這樣的:
一個對象的方法像這樣[obj foo]蔬充,編譯器轉(zhuǎn)成消息發(fā)送objc_msgSend(obj, foo)蝶俱,Runtime時執(zhí)行的流程是這樣的:
首先,通過obj的isa指針找到它的 class ;
在 class 的 method list 找 foo ;
如果 class 中沒到 foo饥漫,繼續(xù)往它的 superclass 中找 ;
一旦找到 foo 這個函數(shù)榨呆,就去執(zhí)行它的實(shí)現(xiàn)IMP 。
7.什么是指針常量和常量指針
指針常量:(指針變量前加const) int *const p;指針本身是一個常量庸队。在聲明的時候初始化积蜻,里面的值(存放的地址)不能更改。
常量指針:(在類型前加const) const int *p;指針本身是一個變量彻消,初始化是最好給一個常量的地址竿拆,它里面值(存放的地址)可以改變。
8.若你去設(shè)計(jì)一個通知中心宾尚,你會怎樣設(shè)計(jì)丙笋?
傳送門
NSNotification:這是一個包裝通知信息的類,類似一個model,存儲了notificationName,object,userInfo等信息.
NSNotificationCenter:顧名思義~通知中心,就是用來管理通知的接收和發(fā)送的類.
1.定義一個類TestNotification,用來存儲notificationName,object,userInfo等信息.這里我們仿照系統(tǒng)的API進(jìn)行設(shè)計(jì).這里另外加了兩個參數(shù)observer和selector.
2.設(shè)計(jì)通知中心類TestNotificationCenter,同樣仿照系統(tǒng)的API進(jìn)行設(shè)計(jì).
9. KVO、KVC的實(shí)現(xiàn)原理
KVO是基于runtime機(jī)制實(shí)現(xiàn)的
當(dāng)某個類的屬性對象第一次被觀察時煌贴,系統(tǒng)就會在運(yùn)行期動態(tài)地創(chuàng)建該類的一個派生類御板,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內(nèi)實(shí)現(xiàn)真正的通知機(jī)制
如果原類為Person牛郑,那么生成的派生類名為NSKVONotifying_Person
每個類對象中都有一個isa指針指向當(dāng)前類怠肋,當(dāng)一個類對象的第一次被觀察,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類淹朋,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法
鍵值觀察通知依賴于NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:笙各;在一個被觀察屬性發(fā)生改變之前, willChangeValueForKey:一定會被調(diào)用础芍,這就 會記錄舊的值杈抢。而當(dāng)改變發(fā)生后,didChangeValueForKey:會被調(diào)用者甲,繼而 observeValueForKey:ofObject:change:context: 也會被調(diào)用春感。
補(bǔ)充:KVO的這套實(shí)現(xiàn)機(jī)制中蘋果還偷偷重寫了class方法砌创,讓我們誤認(rèn)為還是使用的當(dāng)前類虏缸,從而達(dá)到隱藏生成的派生類
KVC底層實(shí)現(xiàn)原理(如下)
KVC運(yùn)用了一個isa-swizzling技術(shù). isa-swizzling就是類型混合指針機(jī)制, 將2個對象的isa指針互相調(diào)換, 就是俗稱的黑魔法.
KVC主要通過isa-swizzling, 來實(shí)現(xiàn)其內(nèi)部查找定位的. 默認(rèn)的實(shí)現(xiàn)方法?由NSOject提供isa指針, 如其名稱所指,(就是is a kind of的意思), 指向分發(fā)表對象的類. 該分發(fā)表實(shí)際上包含了指向?qū)崿F(xiàn)類中的方法的指針, 和其它數(shù)據(jù)。
首先搜索setKey:方法.(key指成員變量名, 首字母大寫)
2嫩实、上面的setter方法沒找到, 如果類方法accessInstanceVariablesDirectly返回YES. 那么按 _key, _isKey刽辙,key, iskey的順序搜索成員名.(NSKeyValueCodingCatogery中實(shí)現(xiàn)的類方法, 默認(rèn)實(shí)現(xiàn)為返回YES)
3、如果沒有找到成員變量, 調(diào)用setValue:forUnderfinedKey:
HTTP和HTTPs的請求過程甲献?
http://www.reibang.com/p/55cb014f6079
說說你理解weak屬性宰缤?
Runtime維護(hù)了一個weak表,用于存儲指向某個對象的所有weak指針。weak表其實(shí)是一個hash(哈希)表慨灭,Key是所指對象的地址朦乏,Value是weak指針的地址(這個地址的值是所指對象的地址)數(shù)組。
1氧骤、初始化時:runtime會調(diào)用objc_initWeak函數(shù)呻疹,初始化一個新的weak指針指向?qū)ο蟮牡刂贰?/p>
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表中刪除,最后清理對象的記錄颅筋。
追問的問題一:
1.實(shí)現(xiàn)weak后宙暇,為什么對象釋放后會自動為nil?
runtime 對注冊的類议泵, 會進(jìn)行布局占贫,對于 weak 對象會放入一個 hash 表中。 用 weak 指向的對象內(nèi)存地址作為 key先口,當(dāng)此對象的引用計(jì)數(shù)為 0 的時候會 dealloc型奥,假如 weak 指向的對象內(nèi)存地址是 a ,那么就會以 a 為鍵碉京, 在這個 weak 表中搜索厢汹,找到所有以 a 為鍵的 weak 對象,從而設(shè)置為 nil 谐宙。
追問的問題二:
2.當(dāng)weak引用指向的對象被釋放時烫葬,又是如何去處理weak指針的呢?
1凡蜻、調(diào)用objc_release
2搭综、因?yàn)閷ο蟮囊糜?jì)數(shù)為0,所以執(zhí)行dealloc
3划栓、在dealloc中兑巾,調(diào)用了_objc_rootDealloc函數(shù)
4、在_objc_rootDealloc中忠荞,調(diào)用了object_dispose函數(shù)
5蒋歌、調(diào)用objc_destructInstance
6帅掘、最后調(diào)用objc_clear_deallocating,詳細(xì)過程如下:
a. 從weak表中獲取廢棄對象的地址為鍵值的記錄
b. 將包含在記錄中的所有附有 weak修飾符變量的地址,賦值為 nil
c. 將weak表中該記錄刪除
d. 從引用計(jì)數(shù)表中刪除廢棄對象的地址為鍵值的記錄
10.iOS本地?cái)?shù)據(jù)存儲安全
11.BAD_ACCESS的錯誤嗎堂油?你是怎樣調(diào)試的修档?
BAD_ACCESS:不管什么時候當(dāng)你遇到BAD_ACCESS這個錯誤,那就意味著你向一個已經(jīng)釋放的對象發(fā)送消息府框。
BAD_ACCESS的本質(zhì):
在C和OC中萍悴,你一直在處理指針,指針無非是存儲另一個變量的內(nèi)存地址的變量寓免。當(dāng)向一個對象發(fā)送消息時癣诱,指向該對象的指針將會被引用,這意味著袜香,你獲取了指針?biāo)傅膬?nèi)存地址撕予,并訪問該存儲區(qū)域的值。
當(dāng)該存儲器區(qū)域不再映射到你的應(yīng)用時蜈首,或者換句話說实抡,該內(nèi)存區(qū)域在你認(rèn)為使用的時候沒有使用,該內(nèi)存區(qū)域是無法訪問的欢策,這時內(nèi)核會拋出一個異常(EXC)吆寨,表明你的應(yīng)用程序不能訪問該存儲器區(qū)域(BAD_ACCESS).
當(dāng)你碰到BAD_ACCESS,這意味著你試圖發(fā)送消息到的內(nèi)存塊踩寇,但內(nèi)存塊無法執(zhí)行該消息啄清。但是,在某些情況下俺孙,BAD_ACCESS是由被損壞的指針引起的辣卒,每當(dāng)你的應(yīng)用程序嘗試引用損壞的指針,一個異常就會被內(nèi)核拋出睛榄。
調(diào)試請看
12荣茫、不借用第三個變量,如何交換兩個變量的值场靴?要求手動寫出交換過程啡莉。
int a = 10,b = 20;
a = a+b;
b = a - b;
a = a - b;
//第二種方法,位異或運(yùn)算
a = a^b;
b = a^b;
a = a^b;
//第三種方法旨剥,使用指針
int *pa = &a;
int *pb = &b;
*pa = b;
*pb = a;
NSLog(@"after,a = %d",a);
NSLog(@"after,b = %d",b);
13.用遞歸算法求1到n的和
int sum(int n)
{
if (n==1)
return 1;
else
return sum(n-1)+n;
}
14.category為什么不能添加屬性咧欣?
Category不能添加成員變量,可以添加屬性泞边,但是屬性要手動實(shí)現(xiàn)setter和getter方法该押。
Category的原理
簡單地說就是通過runtime動態(tài)的吧Category中的方法等添加到類中疗杉,
從category的定義也可以看出category的可為(可以添加實(shí)例方法阵谚,類方法蚕礼,甚至可以實(shí)現(xiàn)協(xié)議,添加屬性)和不可為(無法添加實(shí)例變量)梢什。
經(jīng)過編譯的類在程序啟動后就被runtime加載奠蹬,沒有機(jī)會調(diào)用addIvar。程序在運(yùn)行時動態(tài)構(gòu)建的類需要在調(diào)用objc_registerClassPair
之后才可以被使用嗡午,同樣沒有機(jī)會再添加成員變量囤躁。
category為什么只能添加方法
因?yàn)榉椒ê蛯傩圆⒉弧皩儆凇鳖悓?shí)例,而成員變量“屬于”類實(shí)例荔睹。我們所說的“類實(shí)例”概念狸演,指的是一塊內(nèi)存區(qū)域,包含了isa指針和所有的成員變量僻他。所以假如允許動態(tài)修改類成員變量布局宵距,已經(jīng)創(chuàng)建出的類實(shí)例就不符合類定義了,變成了無效對象吨拗。但方法定義是在objc_class中管理的满哪,不管如何增刪類方法,都不影響類實(shí)例的內(nèi)存布局劝篷,已經(jīng)創(chuàng)建出的類實(shí)例仍然可正常使用哨鸭。
Category注意事項(xiàng):
1、category的方法沒有“完全替換掉”原來類已經(jīng)有的方法娇妓,也就是說如果category和原來類都有methodA像鸡,那么category附加完成之后,類的方法列表里會有兩個methodA
2哈恰、category的方法被放到了新方法列表的前面坟桅,而原來類的方法被放到了新方法列表的后面,這也就是我們平常所說的category的方法會“覆蓋”掉原來類的同名方法蕊蝗,這是因?yàn)檫\(yùn)行時在查找方法的時候是順著方法列表的順序查找的仅乓,它只要一找到對應(yīng)名字的方法,就會罷休_蓬戚,殊不知后面可能還有一樣名字的方法夸楣。
詳細(xì)請點(diǎn)擊
15.runloop和線程的關(guān)系
runloop 正如其名,loop是一種循環(huán)子漩,和run放在一起就是表示一直在運(yùn)行著循環(huán)豫喧,實(shí)際上Runloop和線程是緊密相連的,可以這樣說run loop是為了線程而生幢泼,沒有線程紧显,它就沒有存在必要。每個線程缕棵,包括程序的主線程( main thread )都有與之相應(yīng)的 run loop 對象孵班。
主線程是默認(rèn)開啟的涉兽,其他線程需要手動開啟
16、說一下autoreleasePool的實(shí)現(xiàn)原理篙程。
autoreleasePool自動釋放池是OC的一種內(nèi)存自動回收機(jī)制枷畏,它可以延時加入autoreleasePool中的變量release的時機(jī),在正常情況下虱饿,創(chuàng)建的變量會在超出其作用于的時候release拥诡,但是如果將變量加入autoreleasePool,那么release將延遲執(zhí)行氮发。
AutoreleasePool創(chuàng)建是在一個RunLoop事件開始之前(push)渴肉,AutoreleasePool釋放是在一個RunLoop事件即將結(jié)束之前(pop)。
AutoreleasePool里的Autorelease對象的加入是在RunLoop事件中爽冕,AutoreleasePool里的Autorelease對象的釋放是在AutoreleasePool釋放時宾娜。
單個自動釋放池的執(zhí)行過程就是objc_autoreleasePoolPush() —> [object autorelease] —> objc_autoreleasePoolPop(void *)
17、說一下簡單工廠模式扇售,工廠模式以及抽象工廠模式前塔?
18、如何設(shè)計(jì)一個網(wǎng)絡(luò)請求庫承冰?
19纯丸、delegate
代理(delegate)的主旨是:定義一套接口搔扁,某個對象若想接受另一個對象的委托,則需遵從此接口,以便成為其委托對象礁哄,而這另一個對象的委托胀葱,則需遵從此接口碱妆,以便成為其委托對象辛馆,而這另一個對象則可以給其委托對象回傳一些信息,也可以發(fā)生相關(guān)事件時通知委托對象百宇。
注意delegate需定義成weak考廉。因?yàn)閮烧咧g必須為"非擁有關(guān)系",通常情況下携御,扮演delegate的那個對象也要持有本對象昌粤。
20、說一下多線程啄刹,你平常是怎么用的涮坐?
21、說一下UITableViewCell的卡頓你是怎么優(yōu)化的誓军?
1.UITableViewCell重用機(jī)制袱讹?
UITableView只會創(chuàng)建一屏幕(或者一屏幕多一點(diǎn))的cell,其他都是取出來重用的昵时。每當(dāng)cell滑出屏幕的時候捷雕,就會放到一個集合中椒丧,當(dāng)要顯示某一位置的cell時,會先去集合中取非区,有的話,就直接拿出來顯示盹廷,沒有在創(chuàng)建征绸。
2.tableView滑動為什么會卡頓?
cell賦值內(nèi)容時俄占,會根據(jù)內(nèi)容設(shè)置布局管怠,也就可以知道cell的高度,若有1000行缸榄,就會調(diào)用1000次 cellForRow方法渤弛,而我們對cell的處理操作,都是在這個方法中賦值甚带,布局等等她肯,開銷很大。
3.優(yōu)化方法鹰贵?
3.1優(yōu)化:heightForRow方法處理cell高度晴氨。
思路:賦值和計(jì)算布局分離。cellForRow負(fù)責(zé)賦值碉输,heightRorRow負(fù)責(zé)計(jì)算高度籽前。
3.2自定義cell繪制:
各個信息都是根據(jù)之前算好的布局進(jìn)行繪制的。需要異步繪制敷钾。重寫draeRect方法就不需要異步繪制了枝哄,因?yàn)閐rawRect本來就是異步繪制的。圖文混排的繪制阻荒,coreText繪制挠锥。
3.3按需加載(UIScrollView方面):
如果目標(biāo)行與當(dāng)前行相差超過指定行數(shù),只在目標(biāo)滾動范圍的前后制定n行加載侨赡。滾動很快時瘪贱,只加載目標(biāo)范圍內(nèi)得cell,這樣按需加載辆毡,極大地提高了流暢性菜秦。
4.總結(jié)
1.提前計(jì)算并緩存好高度,因?yàn)閔eightForRow最頻繁的調(diào)用舶掖。
2.異步繪制球昨,遇到復(fù)雜界面,性能瓶頸時眨攘,可能是突破口主慰。
3.滑動時按需加載嚣州,這個在大量圖片展示,網(wǎng)絡(luò)加載時共螺,很管用该肴。(SDWebImage已經(jīng)實(shí)現(xiàn)異步加載)。
4.重用cells藐不。
5.如果cell內(nèi)顯示得內(nèi)容來自web匀哄,使用異步加載,緩存結(jié)果請求雏蛮。
6.少用或不用透明圖層涎嚼,使用不透明視圖。
7.盡量使所有的view opaque挑秉,包括cell本身法梯。
8.減少subViews
9.少用addView給cell動態(tài)添加view,可以初始化的時候就添加犀概,然后通過hide控制是否顯示立哑。
22、看過哪些三方庫姻灶?說一下實(shí)現(xiàn)原理以及好在哪里刁憋?
23、說一下HTTP協(xié)議以及經(jīng)常使用的code碼的含義木蹬。
24至耻、設(shè)計(jì)一套緩存策略。
不清楚 有知道的可以回答下
25镊叁、HTTP協(xié)議 HTTPS
HTTP協(xié)議:即超文本傳輸協(xié)議尘颓,是一種詳細(xì)規(guī)定了瀏覽器和萬維網(wǎng)服務(wù)器之間互相通信的規(guī)則,通過因特網(wǎng)傳送萬維網(wǎng)文檔的數(shù)據(jù)傳送協(xié)議
HTTP協(xié)議作用:HTTP協(xié)議是用于從www服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議晦譬,它可以使瀏覽器更加高效疤苹,使網(wǎng)絡(luò)傳輸減少,它不僅保證計(jì)算機(jī)正確快速的傳輸超文本文檔敛腌,還確定傳輸文檔的哪一部分卧土,以及哪部分內(nèi)容首先顯顯示等。
URL:我們在瀏覽器的地址欄里輸入的網(wǎng)站地址叫做URL (Uniform Resource Locator像樊,統(tǒng)一資源定位符)尤莺。就像每家每戶都有一個門牌地址一樣,每個網(wǎng)頁也都有一個Internet地址生棍。當(dāng)你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時颤霎,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協(xié)議(HTTP),將Web服務(wù)器上站點(diǎn)的網(wǎng)頁代碼提取出來友酱,并翻譯成漂亮的網(wǎng)頁晴音。
HTTPS::是以安全為目標(biāo)的HTTP通道,簡單講HTTP的安全版缔杉,即HTTP下加入SSL層锤躁,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL或详。
26系羞、設(shè)計(jì)一個檢測主線和卡頓的方案。
27鸭叙、說一下runtime觉啊,工作是如何使用的拣宏?看過runtime源碼嗎沈贝?
28、說幾個你在工作中使用到的線程安全的例子勋乾。
29宋下、用過哪些鎖?哪些鎖的性能比較高辑莫?
30学歧、說一下HTTP和HTTPs的請求過程?
在HTTP/1.1協(xié)議中各吨,定義了8種發(fā)送HTTP請求的方法
GET枝笨、POST、OPTIONS揭蜒、HEAD横浑、PUT、DELETE屉更、TRACE徙融、CONNECT、PATCH
各個方法的解釋如下(所有方法全為大寫):
GET: 請求獲取Request-URI所標(biāo)識的資源
POST: 在Request-URI所標(biāo)識的資源后附加新的數(shù)據(jù)
HEAD: 請求獲取由Request-URI所標(biāo)識的資源的響應(yīng)消息報頭
PUT: 請求服務(wù)器存儲一個資源瑰谜,并用Request-URI作為其標(biāo)識
DELETE: 請求服務(wù)器刪除Request-URI所標(biāo)識的資源
TRACE: 請求服務(wù)器回送收到的請求信息欺冀,主要用于測試或診斷
CONNECT: 保留將來使用
OPTIONS: 請求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項(xiàng)和需求
根據(jù)HTTP協(xié)議的設(shè)計(jì)初衷萨脑,不同的方法對資源有不同的操作方式
PUT :增
DELETE :刪
POST:改
GET:查
最常用的是GET和POST(實(shí)際上GET和POST都能辦到增刪改查)
詳細(xì)內(nèi)容
31隐轩、說一下TCP和UDP
32、說一下靜態(tài)庫和動態(tài)庫之間的區(qū)別
33渤早、load和initialize方法分別在什么時候調(diào)用的龙助?
34、NSNotificationCenter是在哪個線程發(fā)送的通知?
35提鸟、用過swift嗎军援?如果沒有,平常有學(xué)習(xí)嗎称勋?
36胸哥、說一下你對架構(gòu)的理解?
37赡鲜、為什么一定要在主線程里面更新UI空厌?
像UIKit這樣大的框架上確保線程安全是一個重大的任務(wù),會帶來巨大的成本银酬。UIKit不是線程安全的嘲更,假如在兩個線程中設(shè)置了同一張背景圖片,很有可能就會由于背景圖片被釋放兩次揩瞪,使得程序崩潰赋朦。或者某一個線程中遍歷找尋某個subView李破,然而在另一個線程中刪除了該subView宠哄,那么就會造成錯亂。apple有對大部分的繪圖方法和諸如UIColor等類改寫成線程安全可用嗤攻,可還是建議將UI操作保證在主線程中毛嫉。