Part One 別人問(wèn)你你都感覺(jué)這尼瑪說(shuō)啥的基礎(chǔ)面試題
1.UIWindow和UIView和 CALayer 的聯(lián)系和區(qū)別?
答:UIView是視圖的基類,UIViewController是視圖控制器的基類珠插,UIResponder是表示一個(gè)可以在屏幕上響應(yīng)觸摸事件的對(duì)象惧磺;
UIwindow是UIView的子類,UIWindow的主要作用:一是提供一個(gè)區(qū)域來(lái)顯示UIView捻撑,二是將事件(event)的分發(fā)給UIView磨隘,一個(gè)應(yīng)用基本上只有一個(gè)UIWindow.
萬(wàn)物歸根,UIView和CALayer都是的老祖都是NSObjet布讹×帐茫可見(jiàn) UIResponder是用來(lái)響應(yīng)事件的,也就是UIView可以響應(yīng)用戶事件描验。
CALayer 和 UIView 的區(qū)別:
1.1 UIView的繼承結(jié)構(gòu)為: UIResponder : NSObject白嘁。
CALayer的繼承結(jié)構(gòu)為: NSObject”炝鳎可見(jiàn) UIResponder是用來(lái)響應(yīng)事件的絮缅,也就是UIView可以響應(yīng)用戶事件,CALayer直接從 NSObject繼承呼股,因?yàn)槿鄙倭薝IResponder類耕魄,不能響應(yīng)任何用戶事件
1.2 所屬框架,UIView是在 /System/Library/Frameworks/UIKit.framework中定義的,UIKit主要是用來(lái)構(gòu)建用戶界面,并且是可以響應(yīng)事件的彭谁。CALayer是在/System/Library/Frameworks/QuartzCore.framework定義的吸奴。而且CALayer作為一個(gè)低級(jí)的,可以承載繪制內(nèi)容的底層對(duì)象出現(xiàn)在該框架中。1.3 UIView相比CALayer最大區(qū)別是UIView可以響應(yīng)用戶事件则奥,而CALayer不可以考润。UIView側(cè)重于對(duì)顯示內(nèi)容的管理,CALayer側(cè)重于對(duì)內(nèi)容的繪制读处。UIView是基于CALayer的高層封裝糊治。
1.4 相似支持1:相似的樹(shù)形結(jié)構(gòu)2:顯示內(nèi)容繪制方式3: 布局約束
總結(jié)一下就是:UIView是用來(lái)顯示內(nèi)容的,可以處理用戶事件.CALayer是用來(lái)繪制內(nèi)容的罚舱,對(duì)內(nèi)容進(jìn)行動(dòng)畫(huà)處理依賴與UIView來(lái)進(jì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本身搀菩,更像是一個(gè)CALayer的管理器呕臂,訪問(wèn)它的跟繪圖和跟坐標(biāo)有關(guān)的屬性,例如frame肪跋,bounds等等歧蒋,實(shí)際上內(nèi)部都是在訪問(wèn)它所包含的CALayer的相關(guān)屬性。
UIView的layer樹(shù)形在系統(tǒng)內(nèi)部州既,被系統(tǒng)維護(hù)著三份copy(這段理解有點(diǎn)吃不準(zhǔn))谜洽。
第一份,邏輯樹(shù)吴叶,就是代碼里可以操縱的阐虚,例如更改layer的屬性等等就在這一份。
第二份蚌卤,動(dòng)畫(huà)樹(shù)实束,這是一個(gè)中間層,系統(tǒng)正在這一層上更改屬性逊彭,進(jìn)行各種渲染操作咸灿。
第三份,顯示樹(shù)侮叮,這棵樹(shù)的內(nèi)容是當(dāng)前正被顯示在屏幕上的內(nèi)容避矢。
這三棵樹(shù)的邏輯結(jié)構(gòu)都是一樣的,區(qū)別只有各自的屬性。
UIView的主layer以外审胸,對(duì)它的subLayer亥宿,也就是子layer的屬性進(jìn)行更改,系統(tǒng)將自動(dòng)進(jìn)行動(dòng)畫(huà)生成歹嘹。
CALayer的坐標(biāo)系系統(tǒng)和UIView有點(diǎn)不一樣箩绍,它多了一個(gè)叫anchorPoint的屬性,它使用CGPoint結(jié)構(gòu)尺上,但是值域是0~1材蛛,也就是按照比例來(lái)設(shè)置。這個(gè)點(diǎn)是各種圖形變換的坐標(biāo)原點(diǎn)怎抛,同時(shí)會(huì)更改layer的position的位置卑吭,它的缺省值是{0.5, 0.5},也就是在layer的中央马绝。
哈哈豆赏,這下夠說(shuō)一壺的了把,雖然說(shuō)完感覺(jué)其實(shí)沒(méi)什么卵用富稻,但是記住一定要說(shuō)的繪聲繪色掷邦。
參考鏈接如下:
2. property 都有哪些常見(jiàn)的字段
strong,weak椭赋,retain抚岗,assign,copy nomatic,readonly,
3. strong哪怔,weak宣蔚,retain,assign认境,copy nomatic 等的區(qū)別胚委。
assign: 簡(jiǎn)單賦值,不更改索引計(jì)數(shù)(Reference Counting)對(duì)基礎(chǔ)數(shù)據(jù)類
copy: 建立一個(gè)索引計(jì)數(shù)為1的對(duì)象叉信,然后釋放舊對(duì)象亩冬。對(duì)NSString
retain:釋放舊的對(duì)象,將舊對(duì)象的值賦予輸入對(duì)象茉盏,再提高輸入對(duì)象的索引計(jì)數(shù)為1 ,對(duì)其他NSObject和其子類
weak
和strong
的區(qū)別:weak
和strong
不同的是 當(dāng)一個(gè)對(duì)象不再有strong類型的指針指向它的時(shí)候 它會(huì)被釋放 鉴未,即使還有weak型指針指向它。一旦最后一個(gè)strong
型指針離去 鸠姨,這個(gè)對(duì)象將被釋放铜秆,所有剩余的weak
型指針都將被清除。
copy
與retain
:
-
copy
其實(shí)是建立了一個(gè)相同的對(duì)象讶迁,而retain不是. -
copy
是內(nèi)容拷貝连茧,retain
是指針拷貝. -
copy
是內(nèi)容的拷貝 ,對(duì)于像NSString,的確是這樣,如果拷貝的是NSArray
這時(shí)只是copy
了指向array中相對(duì)應(yīng)元素的指針.這便是所謂的"淺復(fù)制".
atomic
是Objc使用的一種線程保護(hù)技術(shù),基本上來(lái)講啸驯,是防止在寫(xiě)未完成的時(shí)候被另外一個(gè)線程讀取客扎,造成數(shù)據(jù)錯(cuò)誤。而這種機(jī)制是耗費(fèi)系統(tǒng)資源的罚斗,所以在iPhone這種小型設(shè)備上徙鱼,如果沒(méi)有使用多線程間的通訊編程,那么nonatomic是一個(gè)非常好的選擇针姿。
對(duì)于 NSString 為什么使用 copy 參考這篇鏈接
http://southpeak.github.io/blog/2015/05/10/ioszhi-shi-xiao-ji-di-%5B%3F%5D-qi-2015-dot-05-dot-10/
4.__block
和__weak
修飾符的區(qū)別:
-
__block
不管是ARC還是MRC模式下都可以使用袱吆,可以修飾對(duì)象,還可以修飾基本數(shù)據(jù)類型距淫。 -
__weak
只能在ARC模式下使用绞绒,也只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型(int)榕暇。 -
__block
對(duì)象可以在block中被重新賦值蓬衡,__weak
不可以。
4.常見(jiàn)的 Http 狀態(tài)碼有哪些彤枢?
http狀態(tài)嗎 :302 是請(qǐng)求重定向狰晚。500以上是服務(wù)器錯(cuò)誤。400以上是請(qǐng)求鏈接錯(cuò)誤或者找不到服務(wù)器缴啡。200以上是正確家肯。100以上是請(qǐng)求接受成功。
2-3問(wèn)題參考鏈接http://zhangmingwei.iteye.com/blog/1748431
5.單例的寫(xiě)法盟猖。在單例中使用數(shù)組要注意什么?
static PGSingleton *sharedSingleton;
+ (instancetype)sharedSingleton
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedSingleton = [[PGSingleton alloc] init];
});
return sharedSingleton;
}
其實(shí)上面的還不是標(biāo)準(zhǔn)的單例方法换棚,標(biāo)準(zhǔn)的單例方法需要重寫(xiě) copyWithZone
,allocWithZone
,init
,確保以任何方式創(chuàng)建出來(lái)的對(duì)象只有一個(gè)式镐,這里就不詳細(xì)寫(xiě)了。
單例使用 NSMutableArray 的時(shí)候固蚤,防止多個(gè)地方對(duì)它同時(shí)遍歷和修改的話娘汞,需要加原子屬性。并且property用strong夕玩,并且寫(xiě)一個(gè)遍歷和修改的方法你弦。加上鎖. Lock,UnLock.(PS:考慮性能問(wèn)題盡量避免使用鎖,在蘋果的文檔張看到的不要問(wèn)我為什么燎孟,我也忘了自己查去禽作。。)
關(guān)于單例的參考揩页,和不要濫用單例的參考
6.static 關(guān)鍵字的作用
1.函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體旷偿,不同于 auto 變量,該變量的內(nèi)存只被分配一次,
因此其值在下次調(diào)用時(shí)仍維持上次的值萍程;
2.在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn)幢妄,但不能被模塊外其它函數(shù)訪問(wèn);
3.在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用茫负,這個(gè)函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi)蕉鸳;
4.在類中的 static 成員變量屬于整個(gè)類所擁有,對(duì)類的所有對(duì)象只有一份拷貝忍法;
5.在類中的 static 成員函數(shù)屬于整個(gè)類所擁有潮尝,這個(gè)函數(shù)不接收 this 指針,因而只能訪問(wèn)類的static 成員變量缔赠。
7.iOS 中的事件的傳遞:響應(yīng)鏈
簡(jiǎn)要說(shuō)一下:
事件沿著一個(gè)指定的路徑傳遞直到它遇見(jiàn)可以處理它的對(duì)象衍锚。 首先一個(gè)UIApplication 對(duì)象從隊(duì)列頂部獲取一個(gè)事件并分發(fā)(dispatches)它以便處理。 通常嗤堰,它把事件傳遞給應(yīng)用程序的關(guān)鍵窗口對(duì)象戴质,該對(duì)象把事件傳遞給一個(gè)初始對(duì)象來(lái)處理。 初始對(duì)象取決于事件的類型踢匣。觸摸事件告匠。 對(duì)于觸摸事件,窗口對(duì)象首先嘗試把事件傳遞給觸摸發(fā)生的視圖离唬。那個(gè)視圖被稱為hit-test(點(diǎn)擊測(cè)試)視圖后专。 尋找hit-test視圖的過(guò)程被稱為hit-testing, 參見(jiàn) “Hit-Testing Returns the View Where a Touch Occurred.”
運(yùn)動(dòng)和遠(yuǎn)程控制事件。 對(duì)于這些事件输莺,窗口對(duì)象把shaking-motion(搖晃運(yùn)動(dòng))或遠(yuǎn)程控制事件傳遞給第一響應(yīng)者來(lái)處理戚哎。第一響應(yīng)者請(qǐng)參見(jiàn) “The Responder Chain Is Made Up of Responder Objects.”
iOS 使用hit-testing來(lái)找到事件發(fā)生的視圖。 Hit-testing包括檢查觸摸事件是否發(fā)生在任何相關(guān)視圖對(duì)象的范圍內(nèi)嫂用, 如果是型凳,則遞歸地檢查所有視圖的子視圖。在視圖層次中的最底層視圖嘱函,如果它包含了觸摸點(diǎn)甘畅,那么它就是hit-test視圖。等 iOS決定了hit-test視圖之后往弓,它把觸摸事件傳遞給該視圖以便處理疏唾。
8堆和棧的區(qū)別
管理方式:對(duì)于棧來(lái)講,是由編譯器自動(dòng)管理函似,無(wú)需我們手工控制槐脏;對(duì)于堆來(lái)說(shuō),釋放工作由程序員控制撇寞,容易產(chǎn)生memory leak准给。
申請(qǐng)大行蛊印:
棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域露氮。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的蟀架,在 WINDOWS下葛虐,棧的大小是2M(也有的說(shuō)是1M窄刘,總之是一個(gè)編譯時(shí)就確定的常數(shù))拘泞,如果申請(qǐng)的空間超過(guò)棧的剩余空間時(shí),將提示overflow叁扫。因此三妈,能從棧獲得的空間較小。堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)莫绣,是不連續(xù)的內(nèi)存區(qū)域畴蒲。這是由于系統(tǒng)是用鏈表來(lái)存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的对室,而鏈表的遍歷方向是由低地址向高地址模燥。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見(jiàn)掩宜,堆獲得的空間比較靈活蔫骂,也比較大。
碎片問(wèn)題:對(duì)于堆來(lái)講牺汤,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù)辽旋,從而造成大量的碎片,使程序效率降低檐迟。對(duì)于棧來(lái)講补胚,則不會(huì)存在這個(gè)問(wèn)題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列追迟,他們是如此的一一對(duì)應(yīng)糖儡,以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出
分配方式:堆都是動(dòng)態(tài)分配的,沒(méi)有靜態(tài)分配的堆怔匣。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的桦沉,比如局部變量的分配每瞒。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的纯露,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放剿骨,無(wú)需我們手工實(shí)現(xiàn)。
分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu)埠褪,計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址浓利,壓棧出棧都有專門的指令執(zhí)行挤庇,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫(kù)提供的贷掖,它的機(jī)制是很復(fù)雜的嫡秕。