iOS程序員面試分類模擬24_第1頁
iOS程序員面試分類模擬24_第2頁
iOS程序員面試分類模擬24_第3頁
iOS程序員面試分類模擬24_第4頁
iOS程序員面試分類模擬24_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

付費下載

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

iOS程序員面試分類模擬24簡答題1.

id,NSObject,id<NSObject>的區(qū)別是什么?正確答案:NSObject修飾的對象肯定是NSObject對象,但id修飾的對象雖然肯定是Ob(江南博哥)jective-C對象,但不一定是NSObject對象,id類型是一種運行時的動態(tài)類型,編譯器不會對其進行類型檢查。id<NSObject>修飾的對象也是一種動態(tài)類型對象,對象的類型在運行時才確定,但編譯器知道它一定是遵守NSObject協(xié)議的。例如:id<NSObject>常用來定義delegate對象。

idfool;

//是Objective-C對象,但不是NSObject對象

NSObject*foo2;

//NSObject對象

id<NSObject>foo3;

//不是NSObject對象,但是遵守NSObject協(xié)議

2.

CAAnimation的delegate是強引用還是弱引用?正確答案:CAAnimation的delegate(代理)是強引用,是內(nèi)存管理中一個罕見的特例。為了避免循環(huán)引用問題,delegate通常都使用assign或weak修飾表示弱引用,而CAAnimation動畫是異步的,如果動畫的代理是弱應用而不是強應用,那么會導致其隨時都可能被釋放掉。在使用動畫時要注意采取措施避免循環(huán)引用,例如及時在視圖移除之前的合適時機移除動畫。

CAAnimation的代理定義如下,明確說明動畫的代理在動畫對象整個生命周期間是被強引用的,默認為nil。

/*Thedelegateoftheanimation.Thisobjectisretainedforthe

*lifetimeoftheanimationobject.Defaultstonil.Seebelowforthe

*supposeddelegatemethods.*/

@property(nullable,strong)id<CAAnimationDelegate>delegate;

3.

SDWebImage在iOS93DTouch下出現(xiàn)什么問題?正確答案:1)iOS9使用SDWebImage加載圖片時,在SDWebImageDownloaderOperation.m文件內(nèi)有操作可能會在后臺線程中更新UI,可能導致意想不到的結果甚至程序崩潰。因此,在想更新UI時一定要保證將UI更新操作同步到主線程。UI更新同步到主線程有3種方法,推薦使用GCD來實現(xiàn),代碼形式如下:

dispatch_async(dispatch_get_main_queue(),^{

/*這里寫更新UI操作*/

/*寫完UI更新操作要根據(jù)需要重新布局layout*/

});

2)iOS9考慮到HTTP的不安全性,系統(tǒng)要求所有的網(wǎng)絡請求都使用HTTPS,因此之前的HTTP請求會失效報錯,可以通過設置允許繼續(xù)使用HTTP解決,具體在工程的info.plist配置文件中添加如圖所示配置即可(添加AppTransportSecuritySettings配置字段在將其下的AllowArbitaryLoads的值改為YES)。

配置info.plist字段

4.

SDWebImage是什么?加載圖片的原理是什么?正確答案:SDWebImage是一個針對圖片加載的插件庫,提供了一個支持緩存的用于異步加載圖片的下載工具,特別為常用的UI元素:UIImageView、UIButton和MKAnnotationView提供了類別擴展,可以作為一個很方便的工具。其中,SDWebImagePrefetcher可以預先下載圖片,方便后續(xù)使用。

SDWebImage的幾點特性:

1)為UIImageView、UIButton和MKAnnotationView進行了類別擴展,添加了Web圖片和緩存管理。

2)是一個異步圖片下載器。

3)異步的內(nèi)存+硬盤二級緩沖以及自動的緩沖過期處理。

4)后臺圖片解壓縮功能。

5)可以保證相同的URL(圖片的檢索key)不會被重復多次下載。

6)可以保證假的無效URL不會不斷嘗試去加載。

7)保證主線程不會被阻塞。

8)性能高。

9)使用GCD和ARC。

支持的圖片格式:

1)UIImage支持的圖片格式有JPEG、PNG等,包括GIF都可以被支持。

2)Web圖片格式,包括動態(tài)的Web圖片(使用WebPsubspec)。

使用方法示例:

SDWebImage的使用非常簡單,開發(fā)中需要的主要就是為一個UIImageView添加在線圖片,用到的方法主要就是sd_setImageWithURL方法(新版本方法名都加了sd前綴)。sd_setImageWithURL方法提供了幾種重載方法,包括只使用圖片URL參數(shù)的,以及設置占位圖片placeholderImage參數(shù)的等,這個方法也是框架封裝的最頂層的應用方法,開發(fā)中實際主要就用這個方法。以這個方法為入口,可以層層打開往底層看,可以對應到SDWebImage的整個加載邏輯和流程。

/*bjective-C:*/

#import<SDWebImage/UIImageView+WebCache.h>

/*使用SDWebImage框架為UIImageView加載在線圖片*/

[imageViewsd_setImageWithURL:[NSURLURLWithString:@"http://www.***.com/***/image.jpg"]

placeholderImage:[UIImageimageNamed:@"placeholder.png"]];

/*Swift:*/

imageView.sd_setImageWithURL(NSURL(string:"http://www.***.com/***/image.jpg"),placeholderImage:UIImage(imageNamed:"placeholder.png"))

SDWebImage加載圖片的流程原理:

SDWebImage異步加載圖片的使用非常簡單,一個方法調(diào)用即可完成,但實際上這個方法的調(diào)用會使得框架立刻完成一系列的邏輯處理,以最高效的方式加載需要的圖片。具體加載流程邏輯如圖所示。

SDWebImage異步加載圖片流程邏輯圖

根據(jù)流程可以知道,圖片的加載采用了一種二級緩存機制,簡單概括意思就是:能從內(nèi)存緩存直接取就從內(nèi)存緩存取,內(nèi)存緩存沒有就去硬盤緩存里取,再沒有就根據(jù)提供的URL到網(wǎng)上下載(下載自然會慢很多),下載的圖片還有一個解碼的過程,解碼后就可以直接用了,另外下載的圖片會保存到內(nèi)存緩存和硬盤緩存,從而下次再取同樣的圖片就可以直接取了而不用重復下載。

上面的整個流程對應到SDWebImage框架內(nèi)部,依次會挖掘出下面幾個關鍵方法。最外層的是程序員直接調(diào)用的sd_setImageWithURL方法,以此方法為入口依次可能會調(diào)用到后面的方法,來完成上面的整個優(yōu)化加載流程,這里以其中一個入口方法為例:

(1)sd_setImageWithURL

UIImageView(WebCache)的sdsetImageWithURL方法只是個UIView的類擴展接口方法,負責調(diào)用并將參數(shù)傳給UIView(WebCache)的sdintemalSetImageWithWRL方法,參數(shù)這里有圖片的URL和placeholder占位圖片。

(2)sd_internalSetImageWithURL

UIView(WebCache)的sd_internalSetImageWithURL方法先將placeholder占位圖片異步顯示,然后給SDWebImageManager單例發(fā)送loadImageWithURL消息,傳給它URL參數(shù)讓其再給它的SDImageCache對象發(fā)送queryCacheOperationForKey消息先從本地搜索緩存圖片。

(3)loadImageWithURL

收到loadImageWithURL消息后,SDWebImageManager單例向SDImageCache對象發(fā)送queryCacheOperationForKey消息開始在本地搜索緩存圖片,SDImageCache對象先對自己發(fā)送imageFromMemoryCacheForKey消息從內(nèi)存中搜索圖片緩存,搜到則取出圖片并通過SDCacheQueryCompletedBlock回調(diào)返回,否則再對自己發(fā)送diskImageForKey消息去硬盤搜索圖片,搜到則取出圖片通過SDCacheQueryCompletedBlock回調(diào)返回,內(nèi)存和硬盤都搜不到則只好重新下載。

(4)downloadImageWithURL

如果本地搜索失敗,那么SDWebImageManager會新建一個SDWebImageDownloader下載器,并向下載器發(fā)送downloadImageWithURL消息開始下載網(wǎng)絡圖片;下載成功并解碼后一方面將圖片緩存到本地,另一方面取出圖片進行顯示。其中,像圖片下載以及圖片解碼等耗時操作都是異步執(zhí)行,不會拖慢主線程。

SDImageCache在初始化的時候會注冊一些消息通知,在內(nèi)存警告或退到后臺的時候會清理內(nèi)存圖片緩存,應用結束的時候會清理掉過期的圖片。

5.

如何理解消息轉發(fā)機制?正確答案:當一個對象能處理一個消息時,就會執(zhí)行正常的消息傳遞步驟。如果一個對象無法處理這個消息,那么就會進入消息轉發(fā)。默認情況下,如果是以[objectmessage]的方式調(diào)用方法,當object無法響應message時,那么編譯器會報錯。如果是以performSelector的形式來調(diào)用,那么編譯器在編譯時還無法確定類中到底會不會有這個方法的實現(xiàn)。如果沒有該方法的實現(xiàn),那么就會導致程序崩潰。示例代碼如下:

/*person類中并不存在eat方法*/

Person*aperson=[[Personalloc]init];

[apersonperformSelector:@selector(eat)];

控制臺打印結果如下:

[Personeat]:unrecognizedselectorsenttoinstance0x600000029800

上述這段異常信息實際上是由NSObject的doesNotRecognizeSelector:方法所拋出的,此異常信息表明Person類的實例對象無法響應eat方法。在示例中,消息轉發(fā)過程以程序的崩潰而結束,但是開發(fā)者可以利用runtime,在消息轉發(fā)過程中采取一些措施,而避免程序的崩潰。當然,先要理解消息轉發(fā)機制的原理。消息轉發(fā)機制基本分為3個階段。

1.動態(tài)方法解析

對象在收到無法解讀的消息后,將調(diào)用其所屬類的下列類方法:

+(BOOL)resolveInstanceMethod:(SEL)sel

或者

+(BOOL)resolveClassMethod:(SEL)sel

這兩個方法的參數(shù)就是那個未知的方法,返回值都是Boolean類型,表示這個類能否動態(tài)地添加一個新的方法來處理這條消息。在這里可以新增一個處理該消息的方法。

使用這種方法的前提是:相關的方法的實現(xiàn)代碼已經(jīng)寫好,只等著運行期動態(tài)插入類的MethodList中就可以了。此方案常用來實現(xiàn)@dynamic屬性,示例代碼如下:

/*在控制器中調(diào)用Person類的實例方法eat,但是eat方法沒有實現(xiàn)*/

Person*aperson=[[Personalloc]init];

[apersonperformSelector:@selector(eat)];

/*在Person類中為eat動態(tài)添加方法的實現(xiàn)*/

+(BOOL)resolveInstanceMethod:(SEL)sel{

NSString*str=NSStringFromSelector(sel);

if([strisEqualToString:@"eat"]){

IMPimp=method_getImplementation(class_getInstanceMethod(self,@selector(breakfast)));

class_addMethod(self,@selector(eat),imp,"");

}

return[superresolveInstanceMethod:sel];

}

-(void)breakfast{

NSLog(@"我吃了早餐了");

}

程序的打印結果如下所示:

2016-11-0518:25:51.89701[11777:779796]我吃了早餐了

在示例代碼中,先將消息轉化為字符串,然后檢測其是否能夠表示eat方法。若是eat方法,則為其設置方法的實現(xiàn)。程序的打印結果表明,已經(jīng)成功地攔截了消息轉發(fā)并對未知消息(eat)進行了處理。

2.備用接收者

如果在上一步中無法處理消息,那么當前接收者還有第二次機會來處理未知消息,在這一步,runtime會調(diào)用如下方法:

-(id)forwardingTargetForSelector:(SEL)aSelector

方法參數(shù)代表未知消息,如果當前接收者能找到備用接收者,那么將其返回;如果找不到,那么就返回nil。通過此方法可以模擬出“多重繼承”的一些特性。在一個對象內(nèi)部,可能還有一系列其他的對象,該對象可通過此方法將能夠處理未知消息的相關內(nèi)部對象返回,這樣在外界看來,好像是該對象親自處理了這些消息。示例代碼如下:

/*新建一個PersonHelper類*/

@implementationPersonHelper

@interfacePersonHelper:NSObject

-(void)eat;

@end

-(void)eat{

NSLog(@"別人幫我吃東西");

}

@end

/*在Person.m中設置PersonHelper類的實例為屬性*/

@interfacePerson()

@property(nonatomic,strong)PersonHelper*helper;

@end

@implementationPerson

-(instancetype)init{

if(self=[superinit]){

_helper=[[PersonHelperalloc]init];

}

returnself;

}

/*實現(xiàn)forwardingTargetForSelector:方法*/

-(id)forwardingTargetForSelector:(SEL)aSelector{

NSString*str=NSStringFromSelector(aSelector);

if([strisEqualToString:@"eat"]){

return_helper;

}

return[superforwardingTargetForSelector:aSelector];

}

@end

/*在控制器中執(zhí)行eat方法*/

Person*aperson=[[Personalloc]init];

[apersonperformSelector:@selector(eat)];

以上程序的打印結果如下:

2016-11-0518:45:25.87001[11892:788458]別人幫我吃東西

程序打印結果表明,已經(jīng)成功地在第二步中將消息轉發(fā)給其他對象來執(zhí)行了。這里需要注意,開發(fā)者無法操作通過這一步所轉發(fā)的消息。若是想在發(fā)送給備用接收者之前先修改消息內(nèi)容,那就必須采用完整的消息轉發(fā)機制來操作。

3.完整的消息轉發(fā)機制

如果以上兩步都無法處理未知消息,那么唯一能做的就是啟用完整的消息轉發(fā)機制。此時會調(diào)用如下方法:

-(void)forwardInvocation:(NSInvocation*)anInvocation

這里要創(chuàng)建NSInvocation對象,把與尚未處理的那條消息有關的全部細節(jié)都封裝于其中。此對象包含選擇子、目標及參數(shù)。在觸發(fā)NSInvocation對象時,消息派發(fā)系統(tǒng)將消息指派給目標對象。當然,從這個角度看來,這一方法與第二步中的備用接收者的實現(xiàn)效果相等。但是事實上可以在觸發(fā)消息前,先以某種方式改變消息內(nèi)容,例如追加另外一個參數(shù),或者改變消息名稱等。此外,若發(fā)現(xiàn)某個消息不應由本類處理,則應調(diào)用父類同名方法,以便繼承體系中的每個類都有機會處理此請求。

在使用forwardInvocation:方法前,必須重寫以下方法:

-(NSMethodSignature*)methodsignatureForSelector:(SEL)aSelector

消息轉發(fā)機制使用從這個方法中獲取的信息來創(chuàng)建NSInvocation對象。因此,開發(fā)者必須重寫這個方法,為未知消息提供一個合適的方法簽名。示例代碼如下:

/*在Person.m中實現(xiàn)完整的消息轉發(fā)*/

-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{

NSMethodSignature*signature=[supermethodSignatureForSelector:aSelector];

if(!signamre&&[_helpermethodSignatureForSelector:aSelector]){

signature=[_helpermethodSignatureForSelector:aSelector];

}

returnsignature;

}

-(void)forwardInvocation:(NSInvocation*)anInvocation{

if([_helperrespondsToSelector:anInvocation.selector]){

[anInvocationinvokeWithTarget:_helper];

}

}

以上程序的打印結果如下:

2016-11-0519:08:13.46501[11951:796216]別人幫我吃東西

默認情況下,NSObject的forwardInvocation:方法實現(xiàn)只是簡單調(diào)用了doesNotRecognizeSelector:方法,它不會轉發(fā)任何消息。從某種意義上講,forwardInvocation:方法類似一個通知中心,可以將所有未知消息都派發(fā)出去。通過runtime的消息轉發(fā)機制,開發(fā)者可以為程序動態(tài)地增加很多行為,這也是麗試中??嫉闹R,t量。

6.

如何調(diào)試BAD_ACCESS錯誤?正確答案:調(diào)試BAD_ACCESS錯誤是比較困難的事情,BAD_ACCESS錯誤是由于訪問了野指針,但程序不會在野指針出現(xiàn)時或者在訪問野指針的代碼處報錯,這就導致對其難以察覺。調(diào)試BAD_ACCESS錯誤的思路如下。

1.開啟僵尸對象診斷

開啟僵尸對象診斷,利用僵尸對象來對野指針的出現(xiàn)位置提供線索。僵尸對象指的是引用計數(shù)為0被系統(tǒng)回收的對象,但這些對象暫時還存在內(nèi)存中,且理論上還是可以使用的,但是不穩(wěn)定。開啟僵尸對象診斷后,僵尸對象會暫時保持活躍用于調(diào)試,野指針在對象回收后依然指向該僵尸對象,訪問野指針也就是訪問僵尸對象的情況下可以被編輯器檢測出來。這個時候還是會報BAD_ACCESS錯誤,但是后臺會打印出該線索,例如下面的訪問野指針打印的后臺信息:

2017-03-1216:28:31.501Debug[2371:1379247]-[TestViewControllerrespondsToSelector:]messagesenttodeallocatedinstance0x16749682

可以看出消息發(fā)送給了一個僵尸對象,僵尸對象原本是TestViewController的一個實例,但現(xiàn)在該對象被回收了而開發(fā)者還試圖訪問它,由此可以很容易定位問題所在。

另外,開啟僵尸對象診斷的方法為:打開Xcode頂部導航欄的:Product-Scheme-EditScheme,在彈出的界面中選中左側的Run模式,然后勾選右側Dianostics下的ZombieObjects。不同版本Xcode可能選項位置略有差異。

2.Analyze(分析)

僵尸對象診斷可以幫助快速定位多數(shù)情況下的野指針問題,但有時候不能奏效,這個時候只能利用Xcode的Analyze靜態(tài)分析幫助檢查可能存在問題的地方,而仔細檢查問題所在比較費時。

使用方法很簡單,選中Xcode項部導航欄Product-Analyze或使用快捷鍵Command+Shift+B,分析需要花一些時間,然后左側會列出編輯器發(fā)現(xiàn)的存在潛在問題的地方,選中藍色圖標對應的問題項會跳到問題項所在的代碼行。但這只能給出一些潛在提示,幫助搜索問題所在,不一定和出現(xiàn)的bug相關。

7.

instancetype和id有什么區(qū)別?為什么返回類的實例的類方法或?qū)嵗椒ㄊ褂胕nstancetype而不是id?正確答案:instancetype和id都可以用來代表任意類型,將對象類型的確定往后推遲,用于體現(xiàn)Objective-C語言的動態(tài)性,使其聲明的對象具有運行時的特性。

它們的區(qū)別是:instancetype只能作為返回值類型,但在編譯期instancetype會進行類型檢測,因此對于所有返回類的實例的類方法或?qū)嵗椒ǎㄗh返回值類型全部使用instancetype而不是id;id類型既可以作為返回值類型,也可以作為參數(shù)類型,也可以作為變量的類型,但id類型在編譯期不會進行類型檢測。

8.

MRC中通過調(diào)用靜態(tài)方法創(chuàng)建的新對象,不再使用時需要對其發(fā)送release消息嗎?正確答案:不需要再發(fā)送release消息,因為約定靜態(tài)方法創(chuàng)建的對象會自動將其放入自動釋放池,即已對其發(fā)送autorelease消息,所以不可再對其進行手動釋放。MRC中靜態(tài)方法創(chuàng)建新對象的實現(xiàn)模板如下:

/*靜態(tài)構造方法*/

+(instancetype)personWithName:(NSString*)nameage:(NSInteger)age;

+(instaneetype)personWithName:(NSString*)nameage:(NSInteger)age{

Person*person=[[[Personalloc]init]autorelease];

=name;

person.age=age;

returnperson;

}

9.

什么是數(shù)據(jù)庫三級封鎖協(xié)議?正確答案:眾所周知,基本的封鎖類型有兩種:排它鎖(X鎖)和共享鎖(S鎖)。所謂X鎖是事務T對數(shù)據(jù)A加上X鎖時,只允許事務T讀取和修改數(shù)據(jù)A。所謂S鎖是事務T對數(shù)據(jù)A加上S鎖時,其他事務只能再對數(shù)據(jù)A加S鎖,而不能加X鎖,直到事務T釋放數(shù)據(jù)A上的S鎖。若事務T對數(shù)據(jù)A加了S鎖,則事務T就可以對數(shù)據(jù)A進行讀取,但不能進行更新(S鎖因此又稱為讀鎖),在事務T釋放數(shù)據(jù)A上的S鎖以前,其他事務可以再對數(shù)據(jù)A加S鎖,但不能加X鎖,從而可以讀取數(shù)據(jù)A,但不能更新數(shù)據(jù)A。

在運用X鎖和S鎖對數(shù)據(jù)對象加鎖時,還需要約定一些規(guī)則。例如,何時申請X鎖或S鎖、持鎖時間、何時釋放等,這些規(guī)則稱為封鎖協(xié)議(LockingProtocol)。對封鎖方式規(guī)定不同的規(guī)則,就形成了各種不同的封鎖協(xié)議。一般使用三級封鎖協(xié)議,也稱為三級加鎖協(xié)議。該協(xié)議是為了保證正確的調(diào)度事務的并發(fā)操作。三級加鎖協(xié)議是事務在對數(shù)據(jù)庫對象加鎖、解鎖時必須遵守的一種規(guī)則。下面分別介紹這三級封鎖協(xié)議。

(1)一級封鎖協(xié)議

事務T在修改數(shù)據(jù)R之前必須先對其加X鎖,直到事務結束才釋放。事務結束包括正常結束(commit)和非正常結束(rollback)。一級封鎖協(xié)議可以防止丟失修改,并保證事務T是可恢復的,使用一級封鎖協(xié)議可以解決丟失修改問題。在一級封鎖協(xié)議中,如果僅僅是讀數(shù)據(jù)不對其進行修改,是不需要加鎖的,它不能保證可重復讀和不讀“臟”數(shù)據(jù)。

(2)二級封鎖協(xié)議

一級封鎖協(xié)議加上事務T在讀取數(shù)據(jù)R之前必須先對其加S鎖,讀完后方可釋放S鎖。二級封鎖協(xié)議除防止了丟失修改,還可以進一步防止讀“臟”數(shù)據(jù)。但在二級封鎖協(xié)議中,由于讀完數(shù)據(jù)后即可釋放S鎖,所以它不能保證可重復讀。

(3)三級封鎖協(xié)議

一級封鎖協(xié)議加上事務T在讀取數(shù)據(jù)R之前必須先對其加S鎖,直到事務結束才釋放。三級封鎖協(xié)議除防止了丟失修改和不讀“臟”數(shù)據(jù)外,還進一步防止了不可重復讀。

10.

類工廠方法是什么?正確答案:簡單地說,類工廠方法就是用來快速創(chuàng)建對象的類方法,它可以直接返回一個初始化好的對象。UIKit中最典型的類工廠方法就是UIButton的buttonWithType類工廠方法,開發(fā)者使用這個方法指定按鈕的類型就可以快速得到一個該類型的初始化好的按鈕實例對象。該類工廠方法的定義為:

+(instancetype)buttonWithType:(UIButtonType)buttonType;

使用示例代碼如下:

UIButton*customButton=[UIButtonbuttonWithType:UIButtonTypeCustom];

類工廠方法的幾個必備特征如下:

1)一定是類方法。

2)返回值一定是id/instancetype類型,因為要返回一個對象。

3)規(guī)范的方法名會說明類工廠方法返回的是什么對象,一般是以類名首字母小寫開始,例如這里buttonWithType說明返回的是一個button。

11.

類變量的@protected、@private、@public、@package聲明各有什么含義?正確答案:前3個跟一般面向?qū)ο罄锩娴睦^承封裝概念相同。

@protected:表示變量對子類可見,而對于其他類來說變量是私有的,不可訪問。

@private:表示變量完全私有化,只對本類可見,其子類也不可訪問。

@public:公開變量,表示變量對所有類都是開放可見的,都可以訪問。

最后一個@package是Objective-C中特有的一個修飾詞,一般在開發(fā)靜態(tài)類庫的時候會用到,意思是這個關鍵詞修飾的變量對于framework包內(nèi)部來說是@protected類型的,而對于包外來說是@priviate類型的,這樣可以實現(xiàn)包內(nèi)變量的封裝,包內(nèi)可以使用而包外不可用,防止使用該包的人看到這些變量。

12.

網(wǎng)絡圖片處理問題中怎么解決一個相同的網(wǎng)絡地址重復請求的問題?正確答案:可以通過建立一個以圖片下載地址為key,以下載操作為value的字典,圖片地址是唯一的,可以保證key值唯一。當需要加載該圖片時,先根據(jù)key值去本地緩存中找,看該圖片是否已經(jīng)下載,如果key值匹配,那么直接從本地取圖片資源從而避免重復下載操作,如果本地找不到,那么需要根據(jù)key值中的網(wǎng)絡圖片地址重新去網(wǎng)絡上下載。

13.

內(nèi)連接與外連接有什么區(qū)別?正確答案:內(nèi)連接,也稱為自然連接,只有兩個表相匹配的行才能在結果集中出現(xiàn)。返回的結果集是兩個表中所有相匹配的數(shù)據(jù),而舍棄不匹配的數(shù)據(jù)。由于內(nèi)連接是從結果表中刪除與其他連接表中沒有匹配行的所有行,所以內(nèi)連接可能會造成信息的丟失。內(nèi)連接的語法如下:

selectfieidlistfromtablel[inner]jointable2ontable1.column=table.column

內(nèi)連接是保證兩個表中所有的行都要滿足連接條件,而外連接則不然。與內(nèi)連接不同,外連接不僅包含符合連接條件的行,還包括左表(左外連接時)、右表(右外連接時)或兩個邊接表(全外連接)中的所有數(shù)據(jù)行。也就是說,只限制其中一個表的行,而不限制另一個表的行。SQL的外連接共有3種類型:左外連接(關鍵字為LEFTOUTERJOIN)、右外連接(關鍵字為RIGHTOUTERJOIN)和全外連接(關鍵字為FULLOUTERJOIN)。外連接的用法和內(nèi)連接一樣,只是將INNERJOIN關鍵字替換為相應的外連接關鍵字。

內(nèi)連接只顯示符合連接條件的記錄,外連接除了顯示符合連接條件的記錄外,還顯示不符合連接條件的記錄。例如,若用左外連接,還顯示左表中記錄。

例如,有兩個學生表A(見表1)和課程表B(見表2)。表1學生表A學號姓名0001張三0002李四0003王五表2課程表B學號課程名0001數(shù)學0002英語0003數(shù)學0004計算機對表1和表2進行內(nèi)連接后的結果見表3。表3內(nèi)連接結果學號姓名課程名0001張三數(shù)學0002李四英語0003王五數(shù)學對表1和表2進行右外連接后結果見表4。表4右外連接結果學號姓名課程名0001張三數(shù)學0002李四英語0003王五數(shù)學0004

計算機

14.

如何使用GCD實現(xiàn)線程之間的通信?正確答案:在iOS應用程序的開發(fā)中,一般需要在主線程中進行UI刷新。例如,響應單擊、滾動或者拖曳等事件,所以主線程一般也被稱為UI線程。在主線程中,應該盡量避免在主線程中執(zhí)行一些耗時的操作,如文件的上傳和下載等。應該將這些耗時操作放到子線程中執(zhí)行,等子線程的耗時操作執(zhí)行完成后,再通知主線程更新相應的UI。要完成這樣的操作,就必須實現(xiàn)線程之間的通信,GCD是實現(xiàn)線程之間通信的常用方式。示例代碼如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

/*執(zhí)行耗時操作*/

for(inti=0;i<10000;i++){

NSLog(@"i=%i",i);

}

/*回到主線程*/

dispatch_async(dispatch_get_main_queue(),^{

//更新UI

}):

});

先將需要執(zhí)行的耗時操作放入全局并發(fā)隊列中,再使用dispatch_async異步函數(shù)執(zhí)行并發(fā)隊列,這樣就會開啟新的線程執(zhí)行耗時操作,不會阻塞主線程的任務。當耗時任務完成后,通過主隊列回到主線程執(zhí)行相應的UI更新操作。需要強調(diào)的是,當使用主隊列時,無論是使用dispatch_async異步函數(shù),還是使用dispatch_sync同步函數(shù),執(zhí)行的結果是一樣的。因為主隊列是一種特殊的串行隊列,在主隊列中任務總會在主線程中執(zhí)行。

15.

使用dealloc方法釋放對象時,為什么一定要調(diào)用[superdealloc]方法?在何處調(diào)用?正確答案:因為子類的很多實例變量是繼承自父類的,所以要調(diào)用[superdealloc]方法來釋放從父類繼承來的實例變量,實際上還是釋放自己的實例變量,只是繼承來的這部分只能調(diào)用父類的dealloc方法來釋放。

按照自下往上的邏輯,一般要先釋放子類的實例,然后釋放父類的實例。自下往上的原因是,在調(diào)用[superdealloc]方法之前如果不先把子類中的變量從內(nèi)存中釋放掉,容易造成子類中變量的內(nèi)存積壓,導致內(nèi)存泄漏,所以[superdealloc]方法應該在釋放掉子類變量之后最后調(diào)用。當然在ARC中就不需要考慮這些問題了,變量會自動釋放,此方法也不存在了。

16.

整型值和浮點值在賦值操作中如何相互轉換?正確答案:在Objective-C的數(shù)值運算中,表達式中的整型值和浮點值遵循一種隱式轉換的規(guī)則。實例代碼如下:

floatf1=3.141592,f2;

inti1,i2=3;

/*浮點數(shù)轉換為整型*/

i1=f1;

NSLog("f1=%f,i1=%i",f1,i1);

/*整型數(shù)轉換為浮點型*/

f2=i2;

NSLog("f2=%f,i2=%i",f2,i2);

以上代碼段輸出的結果是:

f1=3.141592,i1=3

f2=3.000000,i2=3

其執(zhí)行的過程遵循以下規(guī)則:

1)在Objective-C中,只要將浮點值賦值給整型變量,數(shù)字的小數(shù)部分都會被刪除。因此在程序中,將f1的值指派給i1時,數(shù)據(jù)3.141592的小數(shù)部分將被刪除,這就意味著數(shù)據(jù)中只有整數(shù)的那一部分(即3)被存儲到了i1中。程序的第一行輸出結果就驗證了這種情況。

2)把整型變量的值指派給浮點變量的操作不會引起數(shù)值的任何改變,數(shù)值僅僅由系統(tǒng)自動轉換并存儲到浮點變量中。因此,當把整型變量i2的值指派給浮點型變量f2時,i2的值(即3)由系統(tǒng)進行了正確的轉換并存儲到f2中。程序的第二行輸出結果就驗證了這種情況。

17.

UIView和CALayer的區(qū)別與聯(lián)系是什么?正確答案:1.UIView和CALayer是什么?

CALayer是動畫中經(jīng)常使用的一個類,它包含在QuanzCore框架中。CALayer類在概念上和UIView類似,同樣是一些被層級關系樹管理的矩形塊,也可以包含一些內(nèi)容(像圖片、文本或者背景色),管理子圖層的位置。它們有一些方法和屬性用來做動畫和變換。使用CoreAnimation開發(fā)動畫的本質(zhì)就是將CALayer中的內(nèi)容轉化為位圖供硬件操作。

CALayer是一個比UIView更底層的圖形類,是對底層圖形API(OpenGLES)一層層封裝后得到的一個類,用于展示一些可見的圖形元素,保留了一些基本的圖形化操作,但同時由于相對高度的封裝,使得操作使用變得很簡單。CALayer用于管理圖形元素,甚至可以制作動畫,它保留了一些幾何屬性,如位置、尺寸、圖形變換等。一般的CALaver是作為UIView背后的支持角色,在創(chuàng)建了一個UIViewr的同時也存在一個相應的CALayer。UIView作為CALayer的代理角色去實現(xiàn)一些功能,例如常見的為UIView制作一個圓角,就會用到UIView背后的layer操作:

view.layer.cornerRadius=10;

CALayer可以通過UIView很方便地展示操作UI元素,但是CALayer自身單獨也可以展示和操作可見元素,且靈活度更高,它自身有一些可見可設置的屬性,如背景色、邊框、陰影等。

另外,UIView簡單來說是一個可以在里面渲染可見內(nèi)容的矩形框,它里面的內(nèi)容可以和用戶進行交互,UIView可以對交互事件進行處理。除了其背后CALayer的圖形操作支持,UIView自身也有像設置背景色等最基本的屬性設置。

2.UIView和CALayer的聯(lián)系

UIView和CALayer的主要聯(lián)系上面已經(jīng)提到,CALayer在UIView背后提供更加豐富靈活的圖形操作,UIView作為CALayer的代理更加快速地幫CALayer顯示一些常用的UI元素并提供交互。

另外,UIView類是所有視圖的基類,CALayer是圖層類。事實上,UIView和CAlayer是平行的層級關系。每一個UIView都有一個CALayer實例的圖層屬性,視圖的責任就是創(chuàng)建并管理圖層,以確保當子視圖在層級關系中被添加或者被移除的時候,與它們相關聯(lián)的圖層也同樣在層級關系樹中有相同的操作。

3.UIView和CALayer的區(qū)別

1)CALayer無法響應用戶事件。UIView和CALayer的最明顯區(qū)別在于它們的可交互性,即UIViewr可以響應用戶事件,而CALayer不可以,原因可以從這兩個類的繼承關系上看出(見圖)。UIView是繼承自UIResponder的,決定了UIView類及其子類能夠通過響應鏈(iOS通過視圖層級關系來傳遞觸摸事件)接收并響應用戶事件。而CALayer直接繼承于NSObject類,所以它不清楚具體的響應鏈,也就無法響應用戶事件。

CALayer和UIView繼承關系

2)分工不同。UIView類側重于對顯示內(nèi)容的管理和整體布局,而CALayer側重于顯示內(nèi)容的繪制、顯示和動畫。

3)所屬框架不同。UIView類是屬于UIKit.framework框架的,UIKit框架主要就是用來構建用戶界面的。CALayer類是屬于QuartzCore.framework框架的,而且CALayer是作為一個低級的,可以承載繪制內(nèi)容的底層對象出現(xiàn)在該框架的。

18.

如何使用runtime動態(tài)添加一個類?正確答案:runtime之所以非常強大,很關鍵的一點就是它能夠動態(tài)地創(chuàng)建一個全新的類或?qū)ο?。在runtime.h文件中可以查到動態(tài)創(chuàng)建一個類所涉及的所有函數(shù)。

/*創(chuàng)建一個新類或元類*/

objc_allocateClassPair(Classsuperclass,constchar*name,size_textraBytes)

/*注冊一個通過objc_allocateClassPair方法創(chuàng)建的類*/

objc_registerClassPair(Classcls)

/*銷毀一個類及其元類*/

objc_disposeClassPair(Classcls)

上面3個函數(shù)的作用見表。動態(tài)創(chuàng)建類所涉及的3個函數(shù)函數(shù)名作用objc_allocateClassPair函數(shù)它的作用是創(chuàng)建一個新類或元類。如果開發(fā)者想讓這個類成為基類,那么參數(shù)superclass指定為nil。參數(shù)extraBytes是分配給類和元類對象尾部的索引ivars的字節(jié)數(shù),通常指定為0objc_registerClassPair函數(shù)當創(chuàng)建完新類后,需要調(diào)用這個方法來注冊這個類,之后這個類才可以在程序中使用objc_disposeClassPair函數(shù)用于銷毀一個類及其元類。需要注意的一點是,如果程序運行中還存在類或其子類的實例,那么就不能調(diào)用該方法

那么,如何運用上述3個函數(shù)動態(tài)地添加一個類呢?示例代碼如下:

/*創(chuàng)建一個新類myClass*/

ClassmyClass=objc_allocateClassPair([NSObjectclass],"myClass",0);

/*添加ivar*/

//@encode(aType):返回該類型的C字符串

class_addIvar(myClass,"_address",sizeof(NSString*),log2(sizeof(NSString*)),@encode(NSString*));

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論