1.iOS中的多線程
iOS中的多線程罩扇,是Cocoa框架下的多線程,通過Cocoa的封裝蜂怎,可以讓我們更方便的使用線程穆刻,它對(duì)線程做了封裝,有些封裝杠步,可以讓我們創(chuàng)建對(duì)象氢伟,本身便擁有線程榜轿,也就是說線程的對(duì)象化,從而減少我們的工程朵锣,提供程序的健壯性谬盐。
(1)GCD
GCD是(Grand Central Dispatch)的縮寫,從系統(tǒng)級(jí)別提供的一個(gè)易用的多線程類庫猪勇,具有運(yùn)行時(shí)的特點(diǎn)设褐,能充分利用多核心硬件颠蕴。GCD的API接口為C語言的函數(shù)泣刹,函數(shù)參數(shù)中多數(shù)有Block。
(2)NSOperation與Queue
NSOperation是一個(gè)抽象類犀被,它封裝了線程的細(xì)節(jié)實(shí)現(xiàn)椅您,我們可以通過子類化該對(duì)象,加上NSQueue和面向?qū)ο蟮乃季S寡键,管理多線程程序掀泳。
(3)NSThread
NSThread是一個(gè)控制線程執(zhí)行的對(duì)象,它不如NSOperation抽象西轩,通過它我們可以方便地得到一個(gè)線程员舵,并控制它。但NSThread的線程之間的并發(fā)控制藕畔,是需要我們自己來控制的马僻,可以通過NSCondition實(shí)現(xiàn)。
(4)其他多線程
在Cocoa的框架下注服,通知韭邓、Timer和異步函數(shù)等都有使用多線程。
2.在項(xiàng)目什么時(shí)候選擇使用GCD溶弟,什么時(shí)候選擇NSOperation女淑?
在項(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é)省代碼量裳凸,而Block參數(shù)的使用,會(huì)使代碼更為易懂劝贸,建議在簡(jiǎn)單項(xiàng)目中使用姨谷。
3.什么是Block
對(duì)于閉包(block),有很多定義映九,其中閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)梦湘,這個(gè)定義接近本質(zhì)又較好理解。對(duì)于剛接觸block的同學(xué)件甥,會(huì)覺得有些繞沟使,因?yàn)槲覀兞?xí)慣寫這樣的程序:
main() {
? ? funA();
}
funA() {
? ? ? funB();
}
就是函數(shù)main調(diào)用函數(shù)A,函數(shù)A調(diào)用函數(shù)B……函數(shù)們依次順序執(zhí)行盖呼,但現(xiàn)實(shí)中不全是這樣的惜辑,例如:項(xiàng)目經(jīng)理M,手下有3個(gè)程序員A譬正、B宫补、C,當(dāng)他給程序員A安排實(shí)現(xiàn)功能F1時(shí)曾我,他并不等著A完成之后再去安排B實(shí)現(xiàn)F2粉怕,而是安排給A功能F1,B功能F2抒巢,C功能F3贫贝,然后可能去寫技術(shù)文檔,而當(dāng)A遇到問題時(shí)虐秦,他會(huì)來找項(xiàng)目經(jīng)理M平酿,給A安排工作時(shí),同時(shí)會(huì)告訴A若遇到困難悦陋,如何能找到他報(bào)告問題(例如打他手機(jī)號(hào))蜈彼,這就是項(xiàng)目經(jīng)理M給A的一個(gè)回調(diào)接口,要回調(diào)的操作俺驶,比如接到電話幸逆,百度查詢后,返回網(wǎng)頁內(nèi)容給A暮现,這就是一個(gè)Block还绘,在M交代工作時(shí),已經(jīng)定義好栖袋,并且取得了F1的任務(wù)號(hào)(局部變量)拍顷,卻是在當(dāng)A遇到問題時(shí),才調(diào)用執(zhí)行塘幅,跨函數(shù)在項(xiàng)目經(jīng)理M查詢百度昔案,獲得結(jié)果后回調(diào)該Block尿贫。
4.委托是什么?委托和被委托方的property聲明用什么屬性踏揣?為什么庆亡?
委托:一個(gè)對(duì)象保存另外一個(gè)對(duì)象的引用,被引用的對(duì)象實(shí)現(xiàn)了事先確定的協(xié)議捞稿,該協(xié)議用于將引用對(duì)象中的變化通知給被引用對(duì)象又谋。
委托和被委托方雙方的property聲明屬性都是assign而不是retain,為了避免循環(huán)引用造成的內(nèi)存泄漏娱局。
5.怎樣理解循環(huán)引用的問題彰亥?
不如在main函數(shù)中創(chuàng)建了兩個(gè)類的對(duì)象A和B,現(xiàn)在引用計(jì)數(shù)都是1×逑剑現(xiàn)在讓A和B相互引用(A有一個(gè)屬性是B對(duì)象剩愧,屬性說明是retain;B有一個(gè)屬性是A對(duì)象娇斩,屬性說明是retain),現(xiàn)在兩個(gè)對(duì)象的引用計(jì)數(shù)都增加1穴翩,都變成了2犬第。
現(xiàn)在執(zhí)行:
[A release];
[B release];
此時(shí)創(chuàng)建對(duì)象的main函數(shù)已經(jīng)釋放了自己對(duì)對(duì)象的所有權(quán),但是此時(shí)A和B的引用計(jì)數(shù)都還是1芒帕,因?yàn)樗麄兓ハ嘁昧恕?/p>
這是你發(fā)現(xiàn)A和B將無法釋放歉嗓,因?yàn)橐脶尫臕必須先釋放B,在B的dealloc方法中再釋放A背蟆。同理鉴分,要想釋放B必須先釋放A,在A的dealloc方法中再釋放B带膀。所以這兩個(gè)對(duì)象將一直存在在內(nèi)存中而不釋放志珍。這就是所謂的循環(huán)引用的問題。要想解決這個(gè)問題垛叨,一般的方法可以將引用的屬性設(shè)置為assign伦糯,而不是retain來處理。
6.內(nèi)存管理的幾條原則是什么嗽元?按照默認(rèn)法則敛纲,那些關(guān)鍵字生成的對(duì)象需要手動(dòng)釋放?哪些情況下不需要手動(dòng)釋放剂癌,會(huì)直接進(jìn)入自動(dòng)釋放池淤翔?
當(dāng)使用new、alloc或copy方法創(chuàng)建一個(gè)對(duì)象時(shí)佩谷,該對(duì)象的引用計(jì)數(shù)器+1.如果不需要使用該對(duì)象旁壮,可以向其發(fā)送release或autorelease消息辞做,在其使用完畢時(shí)被銷毀。
如果通過其他方法獲取一個(gè)對(duì)象寡具,則可以假設(shè)這個(gè)對(duì)象引用計(jì)數(shù)+1秤茅,并且被設(shè)置為autorelease,不需要對(duì)該對(duì)象進(jìn)行清理童叠,如果確實(shí)需要retain這個(gè)對(duì)象框喳,則需要使用完畢后release。
如果retain了某個(gè)對(duì)象厦坛,需要release或autorelease該對(duì)象五垮,保持retain方法和release方法使用次數(shù)相等。
使用new杜秸、alloc放仗、copy關(guān)鍵字生成的對(duì)象和retain了的對(duì)象需要手動(dòng)釋放。設(shè)置為autorelease的對(duì)象不需要手動(dòng)釋放撬碟,會(huì)直接進(jìn)入自動(dòng)釋放池诞挨。
7.怎樣實(shí)現(xiàn)一個(gè)單例模式的類?
首先必須創(chuàng)建一個(gè)全局實(shí)例呢蛤,通常存放在一個(gè)全局變量中惶傻,此全局變量設(shè)置為nil。
提供工廠方法對(duì)該全局實(shí)例進(jìn)行訪問其障,檢查該變量是否為nil银室,如果nil就創(chuàng)建一個(gè)新的實(shí)例,最后返回全局實(shí)例励翼。
全局變量的初始化在第一次調(diào)用工廠方法時(shí)會(huì)在+ allocWithZone: 中進(jìn)行蜈敢,所以需要重寫該方法,防止通過標(biāo)準(zhǔn)的alloc方式創(chuàng)建新的實(shí)例汽抚。
為了防止通過copy方法得到新的實(shí)例抓狭,需要實(shí)現(xiàn) - copyWithZone 方法,只需在此方法中返回本身對(duì)象即可殊橙,引用計(jì)數(shù)也不需要進(jìn)行改變辐宾,因?yàn)閱卫J较碌膶?duì)象是不允許銷毀的,所以也就不用保留膨蛮。
由于全局實(shí)例不允許釋放叠纹,所以retain,release敞葛,autorelease方法均需要重寫誉察。
8.@class的作用是什么?
在頭文件中惹谐,一般只需要知道被引用的類的名稱就可以了持偏。不需要知道其內(nèi)部的實(shí)體變量和方法驼卖,所以在頭文件中一般使用@class來聲明這個(gè)名稱是類的名稱。而在實(shí)現(xiàn)類里面鸿秆,因?yàn)闀?huì)用到這個(gè)引用類的內(nèi)部的實(shí)體變量和方法酌畜,所以需要使用#import來包含這個(gè)被引用的類的頭文件。
@class的作用就是告訴編譯器卿叽,有這么一個(gè)類桥胞,用吧,沒有問題考婴。
@class還可以解決循環(huán)依賴的問題贩虾,例如A.h導(dǎo)入了B.h,而B.h導(dǎo)入了A.h沥阱,每個(gè)頭文件的編譯都要讓對(duì)象先編譯成功才行缎罢,使用@class就可以避免這種情況的發(fā)生。
9.KVC是什么考杉?KVO是什么策精?有什么特點(diǎn)?
KVC是鍵值編碼奔则,特點(diǎn)是通過指定要訪問的屬性名字的字符串標(biāo)識(shí)符蛮寂,可以進(jìn)行類的屬性的讀取和設(shè)置。
KVO是鍵值觀察易茬,特點(diǎn)是利用鍵值觀察可以注冊(cè)成為一個(gè)對(duì)象的觀察者,在該對(duì)象的某個(gè)屬性變化時(shí)收到通知及老。
10.MVC是什么抽莱?有什么特性?
MVC是一種設(shè)計(jì)模式骄恶,由模型食铐、視圖、控制器3部分組成僧鲁。
模型:保存應(yīng)用程序數(shù)據(jù)的類虐呻,處理業(yè)務(wù)邏輯的類。
視圖:窗口寞秃,控件和其他用戶能看到的并且能交互的元素斟叼。
控制器:將模型和視圖綁定在一起,確定如何處理用戶輸入的類春寿。
11.id聲明的對(duì)象有什么特性
id聲明的對(duì)象具有運(yùn)行時(shí)的特性朗涩,即可以指向任意類型的Objective-C的對(duì)象。