版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
iOS程序員面試分類模擬23簡答題1.
@synthesize和@dynamic各表示什么?有什么區(qū)別?正確答案:@synthesize修飾的屬性默認(rèn)情況下由系統(tǒng)自動(dòng)合成setter和getter(江南博哥)方法,除非開發(fā)者自己定義了這些方法;@synthesize經(jīng)常用來更改屬性的變量名,系統(tǒng)自動(dòng)合成時(shí)默認(rèn)變量名為_var,即在原變量名前加下畫線。
@dynamic用來明確禁止編譯器自動(dòng)合成屬性存取方法和默認(rèn)變量名_var,由程序員自己手動(dòng)編寫存取方法。
對于@synthesize和@dynamic,由于前者明確讓編譯器自動(dòng)合成存取方法和默認(rèn)變量名,而后者明確禁止編譯器自動(dòng)合成存取方法和默認(rèn)變量名,所以兩者語義沖突,不可同時(shí)使用。
2.
Oracle數(shù)據(jù)庫的一個(gè)表中有若干條數(shù)據(jù),其占用的空間為10M,如果用delete語句刪除表中所有的數(shù)據(jù),那么此時(shí)這個(gè)表所占的空間為多大?正確答案:10M。數(shù)據(jù)庫中delete操作類似于在Windows系統(tǒng)中把數(shù)據(jù)放到回收站,還可以恢復(fù)。因此,它不會(huì)立即釋放所占的存儲(chǔ)空間。如果想在刪除數(shù)據(jù)后立即釋放存儲(chǔ)空間,那么可以使用truncate命令。
3.
用戶下載一個(gè)大圖片,分成很多份下載,如何使用GCD實(shí)現(xiàn)?正確答案:使用DispatchGroup追加block到GlobalGroupQueue,這些block如果全部執(zhí)行完畢,那么就會(huì)執(zhí)行通過dispatch_group_notify添加到主隊(duì)列中的block,進(jìn)行圖片的合并處理。
dispatch_queue_tqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_tgroup=dispatch_group_create();
dispatch_group_async(group,queue,^{/*加載圖片1*/});
dispatch_group_async(group,queue,^{/*加載圖片2*/});
dispatch_group_async(group,queue,^{/*加載圖片3*/});
dispatch_group_notify(group,dispatch_get_main_queue(),^{
//合并圖片
});
4.
如何理解GCD死鎖?正確答案:所謂死鎖,通常指兩個(gè)操作相互等待對方完成,造成死循環(huán),于是兩個(gè)操作都無法完成,就產(chǎn)生了死鎖。下面是一個(gè)死鎖的代碼示例。
intmain(intargc,constchar*argv[]){
@autoreleasepool{
dispatch_sync(dispatch_get_main_queue(),^(void){
NSLog(@"這里死鎖了");
});
}
return0;
}
這個(gè)程序就是典型的死鎖。程序?qū)⒅麝?duì)列和一個(gè)block傳入GCD的同步函數(shù)dispatch_sync中,等待同步函數(shù)執(zhí)行,直到同步函數(shù)返回。但是事實(shí)上,這個(gè)block永遠(yuǎn)不會(huì)被執(zhí)行。因?yàn)閙ain函數(shù)是在主隊(duì)列中的,它是正在被執(zhí)行的任務(wù),而主隊(duì)列中同時(shí)只能有一個(gè)任務(wù)在執(zhí)行,也就是說只有隊(duì)頭的任務(wù)才能被執(zhí)行。由于主隊(duì)列是一個(gè)特殊的串行隊(duì)列,它嚴(yán)格遵循FIFO的原則,所以block中的任務(wù)必須等到main函數(shù)執(zhí)行完,才能被執(zhí)行。另外,dispatch_sync函數(shù)的特性是,只有block中的任務(wù)被執(zhí)行完畢,才會(huì)返回。因此,只要block不被執(zhí)行,它就不會(huì)返回。所以,在這段代碼中,main函數(shù)等待dispatch_sync函數(shù)返回,而dispatch_sync的返回又依賴block執(zhí)行完畢,block的執(zhí)行又需要等待main函數(shù)的執(zhí)行結(jié)束。這樣就造成了三方循環(huán)等待,即死鎖。
可以總結(jié)出GCD死鎖的原因大體有以下兩點(diǎn):
1)GCD函數(shù)未返回,會(huì)阻塞正在執(zhí)行的任務(wù)。這里需要強(qiáng)調(diào)的是,阻塞(blocking)和死鎖(deadlock)是不同的意思。阻塞表示A任務(wù)的執(zhí)行需要等待B任務(wù)的完成,稱作B會(huì)阻塞A,通俗來講就是強(qiáng)制等待的意思。而死鎖表示A任務(wù)和B任務(wù)相互等待,形成阻塞閉環(huán)。
2)隊(duì)列中的任務(wù)無法并發(fā)執(zhí)行。
以上兩點(diǎn),如果同時(shí)出現(xiàn),那么就會(huì)產(chǎn)生阻塞閉環(huán),形成死鎖。所以針對以上情況,只需要消除其中任何一個(gè)因素,就可以打破這個(gè)閉環(huán),避免死鎖。
解決GCD死鎖的方法有以下幾種方式:
1)使用dispatch_async函數(shù)。dispatch_async函數(shù)是異步函數(shù),具備開啟新線程的能力,但是不一定會(huì)開啟新線程。如果傳入的隊(duì)列參數(shù)是主隊(duì)列,那么任務(wù)仍然會(huì)在主線程中等待執(zhí)行,函數(shù)不會(huì)立即返回。如果傳入的隊(duì)列是普通的串行隊(duì)列或者并發(fā)隊(duì)列,那么該函數(shù)就會(huì)立即返回。
2)將有可能形成阻塞閉環(huán)的任務(wù)分別放到不同的隊(duì)列中執(zhí)行。如案例中,可以新建一個(gè)串行隊(duì)列,將block放入自己的串行隊(duì)列中,不再和main函數(shù)除以一個(gè)隊(duì)列,就能夠解決隊(duì)列阻塞,因此避免了死鎖問題。示例代碼如下:
intmain(intargc,constchar*argv[]){
@autoreleasepool{
dispatch_queueserialQueue=dispatch_queue_create("這是一個(gè)串行隊(duì)列",DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue,^(void){
NSLog(@"這里不會(huì)死鎖了");
});
}
return0;
}
另外,有些面試題,如“是否在主線程使用sync函數(shù)就會(huì)造成死鎖”或者“是否在主線程使用sync函數(shù),同時(shí)傳入串行隊(duì)列就會(huì)死鎖”,答案都是否定的,只要能夠真正了解GCD死鎖的原理,就能很好地回答類似問題了。
5.
能否在一個(gè)視圖控制器中嵌入兩個(gè)tableView控制器?正確答案:可以,相當(dāng)于視圖和視圖控制器的嵌套,視圖可以添加子視圖,視圖控制器也可以添加子控制器。這種情況有時(shí)會(huì)被用到而且很重要,但是有一點(diǎn)容易被忽視,就是將子視圖添加到了父視圖卻忘記將對應(yīng)的控制器作為子控制器添加到父控制器,導(dǎo)致子視圖能顯示但是不能響應(yīng)(沒有對接好控制器)。例如在當(dāng)前視圖上放一個(gè)小尺寸的表格組件,也就是在UIViewController上添加一個(gè)UITableViewController子控制器及其子view。
/*假設(shè)有3個(gè)視圖控制器,一個(gè)作為父控制器,兩個(gè)作為子控制器*/
UIViewController*superVC=[[UIViewControlleralloc]init];
UITableViewController*subVC1=[[UITableViewControlleralloc]init];
UITableViewController*subVC2=[[UITableViewControlleralloc]init];
/*將子視圖控制器添加到父視圖控制器(要注意調(diào)整子視圖的尺寸和位置合理顯示,這里忽略)*/
[superVC.viewaddSubview:subVC1.view];
[superVCaddChildViewController:subVC1];
[superVC.viewaddSubview:subVC2.view];
[superVCaddChildViewController:subVC2];
/*子視圖控制器的移除有對應(yīng)的方法,但只能是子視圖控制器主動(dòng)從父視圖控制器中移除*/
[subVC1.viewremoveFromSuperview];
[SubVC1removeFromParentViewController];
[subVC2.viewremoveFromSuperview];
[subVC2removeFromParentViewController];
此外,要注意和presentViewController方法添加子視圖控制器的區(qū)別,上面手動(dòng)添加子視圖控制器是可以自由調(diào)整子視圖的frame的(包括子視圖位置和尺寸),而presentViewController是用于頁面切換,切換后的子頁面會(huì)覆蓋整個(gè)屏幕而不可以自由調(diào)整子頁面位置和尺寸,對應(yīng)的子視圖控制器移除方法為dismissViewControllerAnimated。
/*顯示子視圖控制器,completion后的代碼塊如果不為空,那么添加結(jié)束后會(huì)觸發(fā)*/
[[parentVCpresentViewController:childVCanimated:NOcompletion:nil];
/*移除子視圖控制器,completion后的代碼塊如果不為空,那么添加結(jié)束后會(huì)觸發(fā)*/
[childVCdismissViewControllerAnimated:NOcompletion:nil];
6.
iOS應(yīng)用有哪幾種不同狀態(tài)?分別表示什么含義?正確答案:iOS應(yīng)用在整個(gè)生命周期中會(huì)有不同的狀態(tài),各狀態(tài)可能會(huì)發(fā)生相互的轉(zhuǎn)換,主要狀態(tài)有非運(yùn)行狀態(tài)、不活躍狀態(tài)、活躍狀態(tài)、后臺狀態(tài)和掛起狀態(tài)等。具體含義見表。iOS應(yīng)用的狀態(tài)及其含義狀態(tài)名稱含義非運(yùn)行狀態(tài)(NotRunningState)應(yīng)用還沒有被運(yùn)行起來(用戶沒有單擊圖標(biāo)打開應(yīng)用)或者正在運(yùn)行的過程中被系統(tǒng)中斷了的狀態(tài)不活躍狀態(tài)(InactiveState)應(yīng)用在前臺運(yùn)行但是不接受事件交互(可能在執(zhí)行一些其他的代碼任務(wù)但不需要事件交互)。應(yīng)用通常什么時(shí)候處于這種狀態(tài)喲?例如,在運(yùn)行某個(gè)應(yīng)用時(shí),用戶突然鎖屏了,或者突然強(qiáng)制轉(zhuǎn)去處理一些像來電或短信等系統(tǒng)緊急事件。通常認(rèn)為應(yīng)用在沒有事件處理的情況下都是處于這個(gè)狀態(tài)的活躍狀態(tài)(ActiveState)應(yīng)用的正常使用狀態(tài),這時(shí)候應(yīng)用在前臺運(yùn)行且接受用戶交互事件,是前臺應(yīng)用的正常狀態(tài)后臺狀態(tài)(BackgroundState)應(yīng)用被放到后臺但還可能執(zhí)行一些后臺代碼任務(wù),通常進(jìn)入到這個(gè)后臺狀態(tài)一會(huì)兒之后就會(huì)進(jìn)入下面的掛起狀態(tài),不再執(zhí)行代碼,也就是應(yīng)用先進(jìn)入后臺狀態(tài)然后進(jìn)入掛起狀態(tài)掛起狀態(tài)(SuspendedState)在掛起狀態(tài),雖然應(yīng)用放在內(nèi)存中,但是不執(zhí)行任何代碼,處于“睡眠”狀態(tài)。當(dāng)掛起的應(yīng)用太多導(dǎo)致內(nèi)存低時(shí),系統(tǒng)可能會(huì)自行清理掉掛起的應(yīng)用來騰出空間給前臺活躍的應(yīng)用
應(yīng)用狀態(tài)轉(zhuǎn)換流程如圖所示。
應(yīng)用狀態(tài)轉(zhuǎn)換流程
7.
什么是MVC設(shè)計(jì)模式?正確答案:MVC是iOS開發(fā)中一種很基礎(chǔ)的工程架構(gòu)模式,也是構(gòu)建iOS應(yīng)用的標(biāo)準(zhǔn)模式。它將數(shù)據(jù)模型、UI視圖和邏輯控制器分開并規(guī)定它們之間的通信方式,大大優(yōu)化了程序的結(jié)構(gòu)組織。
M表示Model,專門用來存儲(chǔ)對象數(shù)據(jù)的模型,一般使用一個(gè)繼承NSObject的基本類對模型的數(shù)據(jù)進(jìn)行封裝,在.h文件中聲明一些用來存放數(shù)據(jù)的屬性。在CoreData中模型即ManagedObject。
V表示View的可見元素,展示UI界面給用戶,主要為UIKit中UIView的子類,其中和用戶進(jìn)行交互的視圖元素為UIKit子類UIControl下的子類視圖,非UIControl子類的視圖不能交互。
C表示Controller,邏輯控制器,對應(yīng)于UIKit中UIViewController及其子類控制器,負(fù)責(zé)協(xié)調(diào)View和Model。
Controller和View的通信主要通過一些代理協(xié)議以及block代碼塊等實(shí)現(xiàn);而Controller和Model的通信主要用到Notification消息通知和KVO等典型觀察者模式實(shí)現(xiàn);View和Model是隔離的,不可以直接相互通信。
MVC設(shè)計(jì)模式是官方推薦在iOS開發(fā)中使用的規(guī)范模式,應(yīng)用的數(shù)據(jù)存儲(chǔ)在Model層,邏輯處理在Controller中進(jìn)行,而用戶界面在View中展示。
8.
重載、重寫和隱藏的區(qū)別是什么?正確答案:重載(overload):函數(shù)名相同,函數(shù)的參數(shù)列表不同(包括參數(shù)個(gè)數(shù)和參數(shù)類型),至于返回類型可同可不同。重載發(fā)生在同一個(gè)類的不同函數(shù)之間,是橫向的。重載和多態(tài)性無關(guān)。
重寫(override):主要指父類虛函數(shù)(虛函數(shù)是C++語言概念)的重寫,用來體現(xiàn)多態(tài)性,指子類不想繼承使用父類的方法,通過重寫同一個(gè)函數(shù)來實(shí)現(xiàn)對父類中同一個(gè)函數(shù)的覆蓋,因此又叫函數(shù)覆蓋。重寫的函數(shù)必須和父類一模一樣,包括函數(shù)名、參數(shù)個(gè)數(shù)和類型以及返回值,只是重寫了函數(shù)的實(shí)現(xiàn)。重寫發(fā)生于父類和子類之間,是縱向的。
隱藏:Objective-C中沒有隱藏,典型的C++中有,通過虛函數(shù)和父子類之間的函數(shù)重寫進(jìn)行區(qū)分,此處不再討論。其中,重載和重寫是針對函數(shù)的,而隱藏除了函數(shù)還會(huì)針對成員變量。隱藏發(fā)生在父類和子類之間,隱藏指父類的同名函數(shù)或變量在子類中隱藏,其中只要函數(shù)同名就隱藏,不管參數(shù)相同與否。在子類中父類的同名函數(shù)或變量不可見,但在父類中依然存在。
9.
Objective-C有私有方法嗎?有私有變量嗎?正確答案:Objective-C是否有私有方法和私有變量關(guān)鍵要看私有的定義。私有主要指通過類的封裝性,將不希望讓外界看到的方法或?qū)傩噪[藏在類內(nèi)部,只有該類可以在內(nèi)部訪問,外部不可見不可訪問。
表面上看,Objective-C中是可以實(shí)現(xiàn)私有的變量和方法的,即將它們隱藏不暴露在頭文件中,不可以顯式地直接訪問,但是Objective-C中這種私有并不是絕對的私有,例如即使將變量和方法隱藏在.m實(shí)現(xiàn)文件中,開發(fā)者仍然可以利用KVC或runtime運(yùn)行時(shí)機(jī)制強(qiáng)行訪問沒有暴露在頭文件的變量或方法。
Objective-C中實(shí)現(xiàn)變量和方法“私有”的方式主要有兩種。
1)在類的頭文件中聲明私有變量。
#import<Foundation/Foundation.h>
@interfaceTest:NSObject{
/*頭文件中定義私有變量,默認(rèn)為@protected*/
@private
NSString*major;
}
@end
2)在.m實(shí)現(xiàn)文件頭部的類擴(kuò)展區(qū)域定義私有屬性或方法,其中方法可不用聲明,直接在實(shí)現(xiàn)文件中實(shí)現(xiàn)即可,只要不在頭文件聲明的方法都對外不可見。
#import"Test.h"
@interfaceTest(){
/*類擴(kuò)展區(qū)域定義私有變量,默認(rèn)就是@private*/
intage;
}
/*類擴(kuò)展區(qū)域定義私有屬性*/
@property(nonatomic,copy)NSString*name;
/*類擴(kuò)展區(qū)域定義私有實(shí)例方法(可省略聲明,類方法的作用主要就是提供對外接口的,所以一般不會(huì)定義為私有)*/
-(void)test;
@end
@implementationTest
/*私有實(shí)例方法*/
-(void)test{
NSLog(@"這是個(gè)私有實(shí)例方法!");
}
@end
利用KVC和runtime暴力訪問私有屬性和變量
KVC訪問變量不受私有權(quán)限的限制,訪問代碼如下:
#import"Test.h"
#import<o(jì)bjc/runtime.h>
...
Test*test=[[Testalloc]ink];
/*1.KVO暴力訪問私有屬性和私有變量*/
[testsetValue:@"albert"forKeyPath:@"name"];
NSString*pname=[testvalueForKey:@"name"];
[testsetValue:@"mathmetics"forKeyPath:@"major"];
NSString*pmajor=[testvalueForKey:@"major"];
NSLog(@"pname:%@pmajor:%@",pname,pmajor);
程序的運(yùn)行結(jié)果為:
2017-04-0211:58:56.255723CommandLine[99973:3239125]pname:albertpmajor:mathmetics
運(yùn)行時(shí)可以使用class_copyIvarList函數(shù)獲取類對象的Ivar變量列表,然后可使用object_getIvar和object_setIvar運(yùn)行時(shí)函數(shù)對變量進(jìn)行暴力訪問。
#import"Test.h"
#import<o(jì)bjc/runtime.h>
...
Test*test=[[Testalloc]init];
/*2.運(yùn)行時(shí)暴力訪問私有屬性和私有變量(ARC)*/
/*獲取實(shí)例變量列表*/
unsignedintcount=0;
Ivar*members=class_copyIvarList([Testclass],&count);
/*打印所有的變量名及其類型*/
for(inti=0;i<count;i++){
constchar*memberName=ivar_getName(members[i]);
constchar*memberType=ivar_getTypeEncoding(members[i]);
NSLog(@"name:%stype:%s",memberName,memberType);
}
/*訪問私有屬性和變量*/
Ivarvarname=members[0];
Ivarvarmajor=members[1];
object_setIvar(test,varname,@"albert");
object_setIvar(test,varmajor,@"mathmetics");
NSString*name=object_getIvar(test,varname);
NSString*major=object_getIvar(test,varmajor);
NSLog(@"pname:%@",name);
NSLog(@"pmajor:%@",major);
/*要手動(dòng)釋放*/
free(members);
程序的運(yùn)行結(jié)果為:
2017-04-0212:07:22.105758CommandLine[189:3242353]name:majortype:@"NSString"
2017-04-0212:07:22.105930CommandLine[189:3242353]name:_nametype:@"NSString"
2017-04-0212:07:22.106156CommandLine[189:3242353]pname:albert
2017-04-0212:07:22.106221CommandLine[189:3242353]pmajor:mathmetics
Runtime暴力訪問對象私有方法
和訪問私有變量類似,這里使用class_copyMethodList運(yùn)行時(shí)函數(shù)獲取類對象中的方法列表,然后使用performSelector函數(shù)執(zhí)行某個(gè)方法。這里只展示了實(shí)例方法的訪問,類方法的訪問也類似,另外還可以使用class_addMethod運(yùn)行時(shí)函數(shù)往類對象中強(qiáng)行添加新的方法,具體見MethodSwizzling部分。
#import"Test.h"
#import<o(jì)bjc/runtime.h>
...
Test*test=[[Testalloc]init];
/*運(yùn)行時(shí)暴力訪問私有方法*/
/*獲取類對象方法列表*/
unsignedintcount=0:
Method*methods=class_copyMethodList([Testclass],&count);
/*獲取第一個(gè)方法的方法名*/
SELsel=method_getName(methods[0]);
/*執(zhí)行該方法*/
[testperformSelector:sel];
10.
如何理解多線程?正確答案:多線程(multithreading)指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計(jì)算機(jī)因有硬件的支持而能夠在同一時(shí)間執(zhí)行多個(gè)線程,進(jìn)而提升整體處理性能。要深入了解iOS中的多線程技術(shù),先需要了解以下幾個(gè)概念。
1.進(jìn)程
每個(gè)正在系統(tǒng)上運(yùn)行的程序都是一個(gè)進(jìn)程。每個(gè)進(jìn)程之間是相互獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi)。進(jìn)程在系統(tǒng)內(nèi)存中的關(guān)系如圖所示。
系統(tǒng)內(nèi)存中的進(jìn)程
通過“活動(dòng)監(jiān)視器”可以查看Mac系統(tǒng)中開啟的所有進(jìn)程(見圖)。
活動(dòng)監(jiān)視器中的進(jìn)程
2.線程
線程是一組指令的集合,或者是程序的特殊段,它可以在程序里獨(dú)立執(zhí)行。每個(gè)進(jìn)程包含至少一個(gè)線程。線程基本上是輕量級的進(jìn)程,它負(fù)責(zé)在單個(gè)程序中執(zhí)行多個(gè)任務(wù)。通常由系統(tǒng)負(fù)責(zé)多個(gè)線程的調(diào)度和執(zhí)行。
需要注意的是,在同一個(gè)線程中執(zhí)行的任務(wù)是串行的。也就是說,在同一時(shí)間內(nèi),一個(gè)線程只能執(zhí)行一個(gè)任務(wù)。
線程是程序中一個(gè)單一的順序控制流程。在單個(gè)程序中同時(shí)運(yùn)行多個(gè)線程完成不同的工作,稱為多線程。多線程技術(shù)主要是為了充分利用CPU,提高程序的執(zhí)行效率。多線程之間的關(guān)系如圖所示。
多線程之間的關(guān)系
事實(shí)上,在同一時(shí)間,CPU只能處理一條線程,只有一條線程在執(zhí)行。多線程的并發(fā)執(zhí)行,其實(shí)就是CPU快速地在多條線程之間調(diào)度。如果CPU調(diào)度線程的速度足夠快,那么就會(huì)產(chǎn)生多條線程并發(fā)執(zhí)行的假象。
多線程技術(shù)的優(yōu)點(diǎn)如下:
1)可以很大程度上提高程序的執(zhí)行效率,提高程序的響應(yīng)速度。
2)使用線程可以把占據(jù)時(shí)間長的程序中的任務(wù)放到后臺去處理,這樣就不會(huì)阻塞程序主線程,用戶體驗(yàn)更好(耗時(shí)操作會(huì)卡住主線程,嚴(yán)重影響UI的流暢度)。
3)提高計(jì)算機(jī)資源的利用率,如:更加充分利用內(nèi)存,多CPU計(jì)算機(jī)上提高CPU利用率。
4)將進(jìn)程分塊,優(yōu)化簡化程序邏輯結(jié)構(gòu)。
多線程技術(shù)的缺點(diǎn)如下:
1)多線程程序的代碼會(huì)更加復(fù)雜、難讀,增加交接和維護(hù)難度。
2)創(chuàng)建和調(diào)度線程會(huì)有額外的開銷,線程越多,開銷越大,甚至反而降低程序的性能。
3)通常模型數(shù)據(jù)是在多個(gè)線程間共享的,需要防止線程死鎖情況的發(fā)生。
因此,在實(shí)際使用多線程時(shí),需要適當(dāng)開啟線程,當(dāng)線程使用完成后,需要及時(shí)釋放資源。在最新的iOS技術(shù)中,已經(jīng)很少需要直接操作線程了,因?yàn)樘O果公司已經(jīng)將大部分復(fù)雜的操作封裝好。
11.
CATransition中過渡類型動(dòng)畫有哪幾種type?正確答案:CATransition是CoreAnimation框架提供的轉(zhuǎn)場動(dòng)畫類。開發(fā)者可以通過一組預(yù)定義的轉(zhuǎn)換或者定制的CIFilter實(shí)例來指定轉(zhuǎn)場效果。下面的代碼演示了當(dāng)單擊tabBar按鈕時(shí)的界面切換動(dòng)畫。
-(void)tabBar:(UITabBar*)tabBardidSelectItem:(UITabBarItem*)item{
CATransition*animation=[CATransitionanimation];
animation.duration=0.5:
/*指定效果*/
animation.type=@"reveal";
/*指定效果展示方向*/
animation.subtype=@"fromBottom";
[self.view.layeraddAnimation:animationforKey:nil];
}
其中的type屬性是一個(gè)NSString類型的字符串,指定了轉(zhuǎn)場動(dòng)畫的類型。它有4個(gè)效果可供選擇:
1)fade:淡入淡出的過渡效果。對應(yīng)常量kCATransitionFade。
2)moveIn:新視圖移動(dòng)到舊視圖的上面。對應(yīng)常量kCATransitionMoveIn。
3)push:新視圖將舊視圖推出窗口。對應(yīng)常量kCATransitionPush。
4)reveal:舊視圖移開顯示下面的新視圖。對應(yīng)常量kCATransitionReveal。
需要注意的是,以上4種效果都暴露在CATransition的.h頭文件中,可以安全使用。除此之外,還有一些效果屬于iOS私有的API,在使用這些效果后,應(yīng)用在審核時(shí)有一定被拒絕的風(fēng)險(xiǎn)。這些效果包括:
1)cube:立方體效果。
2)oglFlip:翻轉(zhuǎn)效果。
3)suckEffect:收縮效果。
4)rippleEffect:水滴波紋效果。
5)pageCurl:向上翻頁效果。
6)pageUnCurl:向下翻頁效果。
7)cameraIrisHollowOpen:攝像頭打開效果。
8)cameraIrisHollowClose:攝像頭關(guān)閉效果。
12.
常量和變量有什么區(qū)別?正確答案:在Objective-C中,用來指代數(shù)據(jù)的值有可變和不可變之分。常量表示一些固定的、不會(huì)被修改的數(shù)據(jù)。反之,能改變的數(shù)據(jù)的值就稱為變量。
常量的屬性決定了常量一旦賦值后就不能進(jìn)行二次賦值了,只能讀取數(shù)據(jù),不能再次寫入數(shù)據(jù),每個(gè)常量都必須有唯一的名字和內(nèi)存空間。變量的特性就是可以多次改變值。在程序執(zhí)行期間,變量的值可以隨意改變。
13.
UIKit類要在哪一個(gè)應(yīng)用線程上使用?正確答案:UIKit的界面類只能在主線程上使用,對界面進(jìn)行更新,多線程環(huán)境中要對界面進(jìn)行更新必須要切換到主線程上。
例如下面的問題代碼:
@interfaceTTWaitController:UIViewController
@property(strong,nonatomic)UILabel*alert;
@end
@implementationTTWaitController
-(void)TiewDidLoad
{
CGRectframe=CGRectMake(20,200,200,20);
self.alert=[[UILabelalloc]initWithFrame:frame];
self.alert.text=@"Pleasewait10seconds...";
self.alert.textColor=[UIColorwhiteColor];
[self.viewaddSubview:self.aleft];
NSOperationQueue*waitQueue=[[NSOperationQueuealloc]init];
[waitQueueaddOperationWithBlock:^{
[NSThreadsleepUntilDate:[NSDatedateWithTimeIntervalSinceNow:10]];
self.alert.text=@"Thanks!";
}];
}
@end
@implementationTTAppDelegate
-(BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.window=[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];
self.window.rootViewController=[[TTWaitControlleralloc]init];
[self.windowmakeKeyAndVisible];
returnYES;
}
這段代碼是想提醒用戶等待10s,10s后在標(biāo)簽上顯示“Thanks”,但多線程代碼部分NSOperationQueue的addOperationWithBlock函數(shù)不能保證block里面的語句是在主線程中運(yùn)行的,UILabel顯示文字屬于UI更新,必須要在主線程進(jìn)行,否則會(huì)有未知的操作,無法在界面上及時(shí)正常顯示。
解決方法是將UI更新的代碼寫在主線程上。代碼同步到主線程上主要有3種方法:NSThread、NSOperationQueue和GCD,3個(gè)層次的多線程都可以獲取主線程并同步。
14.
如何理解MVC設(shè)計(jì)模式?正確答案:MVC全名是ModelViewController,是模型(Model)一界面視圖(View)一控制器(Controller)的縮寫,它是一種軟件設(shè)計(jì)規(guī)范,用一種將業(yè)務(wù)邏輯、數(shù)據(jù)、界面顯示分離的方法組織代碼,將業(yè)務(wù)邏輯聚集到Controller中,在改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí),不需要編寫業(yè)務(wù)邏輯。可以用下圖來描述通過控制器實(shí)現(xiàn)的視圖到模型的交互過程。
MVC設(shè)計(jì)模式結(jié)構(gòu)
1.模型對象
模型對象封裝了應(yīng)用程序的數(shù)據(jù),并定義了操控和處理該數(shù)據(jù)的邏輯和運(yùn)算規(guī)則。用戶在視圖層中所進(jìn)行的創(chuàng)建或者修改數(shù)據(jù)的操作,會(huì)通過控制器對象傳達(dá)出去,最終會(huì)創(chuàng)建或更新模型對象。另外,當(dāng)模型對象更改時(shí)(例如,通過網(wǎng)絡(luò)連接接收到新數(shù)據(jù)),模型對象會(huì)通知控制器對象,控制器對象更新相應(yīng)的視圖對象。被模型返回的數(shù)據(jù)是中立的,也就是說模型和數(shù)據(jù)格式無關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)。由于應(yīng)用于模型的代碼只需要寫一次就可以被多個(gè)視圖重用,所以減少了代碼的重復(fù)性。
2.視圖對象
視圖對象是應(yīng)用程序中用戶可以看到并且能夠與之交互的界面。視圖對象對外提供顯示自身和響應(yīng)用戶操作的接口。視圖對象的主要作用就是顯示來自應(yīng)用程序模型對象的數(shù)據(jù),并使該數(shù)據(jù)可被編輯。在iOS應(yīng)用程序開發(fā)中,所有的控件、窗口等都繼承自UIView,對應(yīng)于MVC中的View。
3.控制器對象
在應(yīng)用程序的一個(gè)或多個(gè)視圖對象和一個(gè)或多個(gè)模型對象之間,控制器對象充當(dāng)媒介。因此,控制器對象是同步管理程序,通過控制器對象,視圖對象了解模型對象的更改,反之亦然??刂破鲗ο筮€可以為應(yīng)用程序執(zhí)行設(shè)置和協(xié)調(diào)任務(wù),并管理其他對象的生命周期??刂破鲗ο蠼忉屧谝晥D對象中進(jìn)行的用戶操作,并將新的或更改過的數(shù)據(jù)傳達(dá)給模型對象。模型對象更改時(shí),一個(gè)控制器對象會(huì)將新的模型數(shù)據(jù)傳達(dá)給視圖對象,以便視圖對象可以顯示它。
MVC設(shè)計(jì)模式的低耦合性、高重用性、可維護(hù)性等優(yōu)點(diǎn)顯而易見,使得原本復(fù)雜的代碼與界面的交互變得簡單、清晰、明了,開發(fā)者可以把更多的精力放在前端界面的設(shè)計(jì)上,而不用絞盡腦汁去思考究竟應(yīng)該如何使界面得到同步,這樣減輕了設(shè)計(jì)壓力,也從另一方面使用戶得到更多更好的享受體驗(yàn)。事實(shí)上,MVC設(shè)計(jì)模式也是蘋果公司推薦并在大量實(shí)踐的設(shè)計(jì)模式。例如,對于不同的UIView類型的視圖對象,都有相應(yīng)地控制器對象(即UIViewController)與之對應(yīng)。例如,常用的視圖類UITableView,它所對應(yīng)的控制器對象就是UITableViewController類對象。
15.
如何使用NSURLSession進(jìn)行網(wǎng)絡(luò)請求?正確答案:在2013年的WWDC上,蘋果公司推出了NSURLConnection的替代方案:NSURLSession。和NSURLConnection一樣,NSURLSession指的也不僅是同名類NSURLSession,它還包括一系列相關(guān)聯(lián)的類。NSURLSession包括了與之前相同的組件:NSURLRequest與NSURLCache,但是將NSURLConnection替換成了NSURLSession、NSURLSessionConfiguration及NSURLSessionTask的3個(gè)子類:NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。
與NSURLConnection相比,NSURLSession最直接的改進(jìn)就是可以配置每個(gè)session的緩存、協(xié)議、cookie,以及證書策略(CredentialPolicy),甚至跨進(jìn)程共享這些信息。這將允許程序和網(wǎng)絡(luò)基礎(chǔ)框架之間相互獨(dú)立,不會(huì)發(fā)生干擾。每個(gè)NSURLSession對象都由一個(gè)NSURLSessionConfiguration對象進(jìn)行初始化,后者指定了剛才提到的那些策略以及一些用來增強(qiáng)移動(dòng)設(shè)備上性能的新選項(xiàng)。
NSURLSessionTask負(fù)責(zé)處理數(shù)據(jù)的加載以及文件的數(shù)據(jù)在客戶端與服務(wù)器之間的上傳和下載。它是一個(gè)抽象類,一般使用其子類:NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。這3個(gè)子類封裝了現(xiàn)代程序3個(gè)最基本的網(wǎng)絡(luò)任務(wù):獲取數(shù)據(jù)(如JSON或者XML),上傳文件和下載文件。
NSURLSession相關(guān)類的關(guān)系如圖所示。
NSURLSession相關(guān)類的關(guān)系
如何使用NSURLSession像NSURLConnection那樣發(fā)送一個(gè)請求呢?基本步驟如下:
1)創(chuàng)建NSURLSessionConfiguration對象對NSURLSession進(jìn)行配置。
2)創(chuàng)建NSURLSession對象。
3)利用上一步創(chuàng)建好的NSURLSession對象創(chuàng)建NSURLSessionTask的子類對象。
4)執(zhí)行請求任務(wù)。
下面的示例展示了NSURLSession的基本用法,代碼如下:
-(void)sessionGet{
/*創(chuàng)建NSURL對象*/
NSURL*url=[NSURLURLWithString:IMAGEURL];
/*創(chuàng)建請求對象,默認(rèn)為GET請求*/
NSURLRequest*request=[NSURLRequestrequestWithURL:url];
/*創(chuàng)建配置*/
NSURLSessionConfiguration*config=[NSURLSessionConfigurationdefaultSessionConfigtwation];
/*創(chuàng)建NSURLSession對象*/
NSURLSession*session=[NSURLSessionsessionWithConfiguration:config];
/*創(chuàng)建任務(wù)*/
NSURLSessionDataTask*task=[sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){
if(error){
return;
}
/*解析返回的數(shù)據(jù)*/
_image=[UIImageimageWithData:data];
/*顯示圖片,注意!此時(shí)是異步線程需要在主線程中顯示圖片*/
[selfchangeBg];
}];
[taskresume];
}
16.
QuartzCore和CoreGraphics有什么區(qū)別?正確答案:CoreGra
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026廣東深圳大學(xué)藝術(shù)學(xué)部李象群特聘教授團(tuán)隊(duì)博士后招聘1人備考題庫帶答案詳解(考試直接用)
- 2026新疆圖木舒克市馨潤園藝工程有限公司招聘1人備考題庫及一套參考答案詳解
- 2026上半年安徽事業(yè)單位聯(lián)考合肥新站高新區(qū)管委會(huì)招聘40人備考題庫附答案詳解(基礎(chǔ)題)
- 2026山東濟(jì)南高新區(qū)海川中學(xué)教師崗招聘備考題庫及答案詳解1套
- 2026四川樂山市沐川縣人力資源和社會(huì)保障局招聘城鎮(zhèn)公益性崗位人員10人備考題庫及答案詳解(名師系列)
- 2026廣東佛順德容桂泰安小學(xué)招聘2人備考題庫附答案詳解(精練)
- 2026上半年貴州事業(yè)單位聯(lián)考習(xí)水縣招聘203人備考題庫附參考答案詳解(滿分必刷)
- 2026年福建莆田市城廂區(qū)教師進(jìn)修學(xué)校附屬興安小學(xué)代課教師招聘2人備考題庫含答案詳解(綜合題)
- 2026新疆準(zhǔn)東能源投資(集團(tuán))有限公司 招(競)聘7人備考題庫及參考答案詳解(新)
- 2026廣東清遠(yuǎn)市清城區(qū)信訪局招聘聘員2人備考題庫帶答案詳解(綜合題)
- 2026年山東省威海市單招職業(yè)傾向性測試題庫附答案解析
- 2026新疆伊犁州新源縣總工會(huì)面向社會(huì)招聘工會(huì)社會(huì)工作者3人考試備考試題及答案解析
- 積極思想培訓(xùn)
- 2026年《必背60題》抖音本地生活BD經(jīng)理高頻面試題包含詳細(xì)解答
- 彈藥庫防火防爆消防演示
- 用友實(shí)施方法論課件
- 大地測量控制點(diǎn)坐標(biāo)轉(zhuǎn)換技術(shù)規(guī)程
- 食材配送服務(wù)方投標(biāo)方案(技術(shù)標(biāo))
- 食品安全全球標(biāo)準(zhǔn)BRCGS第9版內(nèi)部審核全套記錄
- TCSAE 261-2022 自主代客泊車 地圖與定位技術(shù)要求
- 成就心態(tài)的感悟
評論
0/150
提交評論