1.INTERVIEW 共勉
2.INTERVIEW 準(zhǔn)備
Interview preparation.png
3.iOS developers 方向
iOS developers.png
4.INTERVIEW QUESTION
4.1深copy和淺copy
淺拷貝.png
淺拷貝:
1.對(duì)內(nèi)存地址的復(fù)制,讓目標(biāo)對(duì)象指針和源對(duì)象指向同一片內(nèi)存空間.
2.內(nèi)存銷(xiāo)毀的時(shí)候,指向這片空間的指針需要重新定義才可以使用,要不然會(huì)成為野指針
3.拷貝指向原來(lái)對(duì)象的指針,使原對(duì)象的引用計(jì)數(shù)加+1
4.相當(dāng)于創(chuàng)建了一個(gè)指向原對(duì)象的新指針,并沒(méi)有創(chuàng)建一個(gè)新的對(duì)象.
深拷貝.png
深拷貝:
1.拷貝對(duì)象的具體內(nèi)容,而內(nèi)存地址是自主分配的
2.拷貝結(jié)束之后,兩個(gè)對(duì)象存在的值是相同的,內(nèi)存地址是不一樣的
3.兩個(gè)對(duì)象沒(méi)有任何關(guān)系
本質(zhì)區(qū)別:
1.深拷貝是內(nèi)容拷貝,淺拷貝是指針拷貝
2.是否有新的內(nèi)存地址
3.是否影響內(nèi)存地址的引用計(jì)數(shù).
案例一
NSString* str1 =@"copyStr";NSMutableString*str2 = [str1copy];NSMutableString*str3 = [str1 mutableCopy];NSLog(@"str1:%p--%@",str1,str1);NSLog(@"str1:%p--%@",str2,str2);NSLog(@"str1:%p--%@",str3,str3);
2018-04-1414:50:54.117652+0800MutyCopy-Copy[2644:63575]str1:0x109a48068--copyStr2018-04-1414:50:54.117885+0800MutyCopy-Copy[2644:63575]str1:0x109a48068--copyStr2018-04-1414:50:54.118010+0800MutyCopy-Copy[2644:63575]str1:0x600000259a40--copyStr
1.str1,str2地址相同,而Str3地址不同
2.NSString的copy是淺拷貝,copy返回的對(duì)象是不可變對(duì)象
3.mutablecopy是深拷貝
*案例二:
NSMutableString* str1 = [NSMutableStringstringWithString:@"mutableStr"];NSMutableString* str2 = [str1copy];NSMutableString* str3 = [str1 mutableCopy];NSLog(@"str:%p-----%@",str1,str1);NSLog(@"str:%p-----%@",str2,str2);NSLog(@"str:%p-----%@",str3,str3);
2018-04-1415:04:50.092820+0800MutyCopy-Copy[2685:70866]str:0x60000025b210-----mutableStr2018-04-1415:04:50.093059+0800MutyCopy-Copy[2685:70866]str:0x60000022ca40-----mutableStr2018-04-1415:04:50.093217+0800MutyCopy-Copy[2685:70866]str:0x60000025b540-----mutableStr
1.str1,str2,str3地址都不同
2.NSMutableString對(duì)象copy與mutableCopy都是深拷貝
3.copy返回的對(duì)象是不可變對(duì)象
4.2 iOS程序的啟動(dòng)過(guò)程
iOS程序的啟動(dòng)過(guò)程.png
首先找到程序入口,執(zhí)行main函數(shù)
main -->>? UIApplicationMain
創(chuàng)建UIApplication對(duì)象
創(chuàng)建UIApplication的代理對(duì)象,給UIApplication對(duì)象代理屬性賦值
開(kāi)啟主運(yùn)行循環(huán),作用接收事件,讓程序一直運(yùn)行
加載info.plist,判斷有沒(méi)有指定main.storyboard,如果指定就去加載.
4.3 loadView
什么時(shí)候被調(diào)用?
每次訪(fǎng)問(wèn)VC的view而且view為nil,loadView方法被調(diào)用
作用
loadView方法是用來(lái)負(fù)責(zé)創(chuàng)建VC的view.
默認(rèn)實(shí)現(xiàn)是怎樣的?
默認(rèn)實(shí)現(xiàn)即[spuer loadView]
1.它會(huì)先去查找與UIViewController相關(guān)聯(lián)的xib文件,通過(guò)加載xib文件來(lái)創(chuàng)建VC的view.
2.如果在初始化VC指定了xib文件名,就會(huì)根據(jù)傳入的xib文件名加載對(duì)應(yīng)的xib文件.如果沒(méi)有明顯xib文件名,就會(huì)加載跟自己同名的xib文件.
3.如果沒(méi)有找到關(guān)聯(lián)的xib文件,就會(huì)創(chuàng)建一個(gè)空白的UIView,然后賦值給VC的view屬性
4.4 單例模式
可以看我簡(jiǎn)書(shū)地址:
http://www.reibang.com/p/9e9b405b4d94
4.5 多線(xiàn)程
進(jìn)程
1.進(jìn)程是指系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序
2.每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專(zhuān)用且受保護(hù)的內(nèi)存空間內(nèi).
線(xiàn)程
1.1個(gè)進(jìn)程要想執(zhí)行任務(wù),必須得有線(xiàn)程,每1個(gè)進(jìn)程至少要有1條線(xiàn)程
2.線(xiàn)程是進(jìn)程的基本執(zhí)行單元
3.一個(gè)進(jìn)程的素有任務(wù)都在線(xiàn)程中執(zhí)行
多線(xiàn)程
1.1個(gè)進(jìn)程中可以開(kāi)啟多條線(xiàn)程,每條線(xiàn)程可以并行(同時(shí))執(zhí)行不同的任務(wù)
2.進(jìn)程--工廠(chǎng),線(xiàn)程--工廠(chǎng)工人
3.多線(xiàn)程可以提高程序的執(zhí)行效率
多線(xiàn)程.png
比如,我們同時(shí)開(kāi)啟2條線(xiàn)程下載文件A,文件B.
多線(xiàn)程的原理
1.同一時(shí)間,CPU只能處理1條線(xiàn)程,只有1條線(xiàn)程在工作
2.多線(xiàn)程并發(fā)執(zhí)行,是CPU快速地在多條線(xiàn)程之間調(diào)度切換
注意:如果線(xiàn)程非常非常多,會(huì)發(fā)生什么情況?
cpu會(huì)在多個(gè)多線(xiàn)程之間進(jìn)行調(diào)度,消耗大量的CPU資源.這樣的話(huà),每條線(xiàn)程被調(diào)度執(zhí)行的頻次會(huì)降低,線(xiàn)程執(zhí)行效率降低.
多線(xiàn)程的優(yōu)缺點(diǎn)
1.優(yōu)點(diǎn):
1.1.能適當(dāng)?shù)奶岣叱绦虻膱?zhí)行效率
1.2.能適當(dāng)調(diào)高資源利用率
2.缺點(diǎn):
2.1.開(kāi)啟線(xiàn)程需要占用一定的內(nèi)存空間,如果開(kāi)啟大量的線(xiàn)程,會(huì)占用大量的內(nèi)存空間,降低程序的性能
2.2線(xiàn)程越多,CPU在調(diào)度線(xiàn)程上的開(kāi)銷(xiāo)就越大.
多線(xiàn)程應(yīng)用
1.什么是主線(xiàn)程?
一個(gè)iOS程序運(yùn)行后,默認(rèn)會(huì)開(kāi)啟1條線(xiàn)程 ,稱(chēng)為主線(xiàn)程
2.主線(xiàn)程的主要作用?
2.1.顯示/刷新UI界面
2.2.處理UI事件
3.主線(xiàn)程使用注意?
3.1.別將比較耗時(shí)的操作放到主線(xiàn)程中
3.2.耗時(shí)操作會(huì)卡住主線(xiàn)程,嚴(yán)重影響UI的流暢度
4.多線(xiàn)程實(shí)現(xiàn)技術(shù)方案?
pthread,NSThread,GCD,NSOperation四中方案.
4.6 NSThread
創(chuàng)建,啟動(dòng)線(xiàn)程
NSThread*thread = [[NSThreadalloc] initWithTarget:selfselector:@selector(threadFun) object:nil];[thread start];
線(xiàn)程一啟動(dòng),就會(huì)告訴CPU準(zhǔn)別就緒,可以隨時(shí)接受CPU調(diào)度.CPU調(diào)度當(dāng)前線(xiàn)程之后,就會(huì)在線(xiàn)程thread中執(zhí)行self的run方法
主線(xiàn)程用法
主線(xiàn)程相關(guān)用法.png
其他方式創(chuàng)建線(xiàn)程
創(chuàng)建線(xiàn)程后自動(dòng)啟動(dòng)線(xiàn)程
[NSThreaddetachNewThreadSelector:@selector(run) toTarget:selfwithObject:nil];
隱式創(chuàng)建并啟動(dòng)線(xiàn)程
[selfperformSelectorInBackground:@selector(run) withObject:nil];
線(xiàn)程狀態(tài)
線(xiàn)程狀態(tài).png
1.啟動(dòng)線(xiàn)程,start.就緒狀態(tài)-->>運(yùn)行狀態(tài).當(dāng)新廠(chǎng)任務(wù)執(zhí)行完畢,自動(dòng)進(jìn)入死亡狀態(tài)
2.阻塞(暫停)線(xiàn)程,進(jìn)入阻塞狀態(tài)
+ (void)sleepUntilDate:(NSDate*)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
3.強(qiáng)制停止線(xiàn)程
進(jìn)入死亡狀態(tài)
注意:一旦線(xiàn)程停止了,就不能再次開(kāi)啟任務(wù).
多線(xiàn)程的安全隱患
1.資源共享
一塊資源可能會(huì)被多個(gè)線(xiàn)程共享,也就是多個(gè)線(xiàn)程可能會(huì)訪(fǎng)問(wèn)同一塊資源.當(dāng)多線(xiàn)程訪(fǎng)問(wèn)同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問(wèn)題.
2.如圖,
線(xiàn)程安全隱患.png
如果,多個(gè)線(xiàn)程訪(fǎng)問(wèn)同一塊資源的話(huà),會(huì)造成數(shù)據(jù)錯(cuò)亂的.
我們應(yīng)該怎么解決呢?
安全隱患解決-互斥鎖.png
3.如圖,
線(xiàn)程A和線(xiàn)程B同時(shí)訪(fǎng)問(wèn)資源變量Integer,
為了防止搶奪資源,
線(xiàn)程A在讀取資源變量Integer之前先加一把鎖,
然后讀取Integer的數(shù)據(jù)并在線(xiàn)程A中完成數(shù)據(jù)操作(17+1=18),
然后把數(shù)據(jù)寫(xiě)入Integer中,
最后開(kāi)鎖Unlock.在線(xiàn)程A對(duì)Integer操作的過(guò)程中,
線(xiàn)程B是無(wú)權(quán)訪(fǎng)問(wèn)Integer的,
只有線(xiàn)程A_Unlock后,線(xiàn)程B才可以訪(fǎng)問(wèn)資源變量Integer.
4.互斥鎖使用格式
@synchronized(self){//需要鎖定的代碼}
注意: 鎖定1分代碼只用1把鎖,用多把鎖是無(wú)效的
5.互斥鎖的優(yōu)缺點(diǎn)
互斥鎖的使用前提:多條線(xiàn)程搶奪同一塊資源
優(yōu)點(diǎn):能有效防止因多線(xiàn)程搶奪資源造成的數(shù)據(jù)安全問(wèn)題
缺點(diǎn):需要消耗大量的CPU
6.nonatomic和atomic
atomic:
原子屬性,為setter方法加鎖(默認(rèn)就是atomic)
線(xiàn)程安全,需要消耗大量的資源
nonatomic:
非原子屬性,不會(huì)為setter方法加鎖
非線(xiàn)程安全,適合內(nèi)存小的移動(dòng)設(shè)備
4.7 GCD
什么是GCD?
全程Grand Central Dispatch,中樞調(diào)度器
純C語(yǔ)言,提供了非常多強(qiáng)大的函數(shù)
GCD的優(yōu)勢(shì)
1.GCD是蘋(píng)果公司為多核的并行運(yùn)算提出的解決方案
2.GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核
3.GCD自動(dòng)管理線(xiàn)程的生命周期(創(chuàng)建線(xiàn)程,調(diào)度任務(wù),銷(xiāo)毀線(xiàn)程)
GCD有2個(gè)核心概念
1.任務(wù):執(zhí)行什么操作
2.隊(duì)列;用來(lái)存放任務(wù)
任務(wù)和隊(duì)列
任務(wù)和隊(duì)列.png
1.執(zhí)行任務(wù)
GCD中有2個(gè)用來(lái)執(zhí)行任務(wù)的函數(shù)
1.1用同步的方式執(zhí)行任務(wù)
dispatch_sync(dispatch_queue_tqueue,dispatch_block_tblock);queue:隊(duì)列block:任務(wù)
1.2用異步的方式執(zhí)行任務(wù)
dispatch_async(dispatch_queue_tqueue,dispatch_block_tblock);
1.3同步和異步的區(qū)別
同步:只能在當(dāng)前線(xiàn)程中執(zhí)行任務(wù),不具備開(kāi)啟新線(xiàn)程的能力
異步:可以再新的線(xiàn)程中執(zhí)行任務(wù),具備開(kāi)啟新線(xiàn)程的能力
隊(duì)列的類(lèi)型
GCD的隊(duì)列可以分為2大類(lèi)型
并發(fā)隊(duì)列:可以讓多個(gè)任務(wù)并發(fā)執(zhí)行(并發(fā)功能只能在異步函數(shù)下才有效)
串行隊(duì)列:讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行
容易混淆的術(shù)語(yǔ)
有4個(gè)術(shù)語(yǔ)比較容易混淆:
同步,異步,并發(fā),串行
同步,異步,并發(fā),串行.png
注意: 同步函數(shù) + 主隊(duì)列 == 死鎖
并發(fā)隊(duì)列
GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列桦山,供整個(gè)應(yīng)用使用阔籽,不需要手動(dòng)創(chuàng)建
使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊(duì)列
dispatch_queue_tdispatch_get_global_queue(dispatch_queue_priority_tpriority,? 隊(duì)列的優(yōu)先級(jí)unsignedlongflags);
全局并發(fā)隊(duì)列dispatch_queue_tqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
全局并發(fā)隊(duì)列的優(yōu)先級(jí).png
串行隊(duì)列
GCD中獲得串行的2中途徑
1.使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列
dispatch_queue_t=dispatch_queue_create(constchar*label,? 隊(duì)列名稱(chēng)dispatch_queue_attr_tattr);? 隊(duì)列屬性,一般用NULL即可
2.使用主隊(duì)列
放在主隊(duì)列中的任務(wù),都會(huì)放到主線(xiàn)程中執(zhí)行
使用dispatch_get_main_queue()獲得主隊(duì)列
dispatch_queue_tqueue= dispatch_get_main_queue();
從子線(xiàn)程回到主線(xiàn)程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{? ? ? 執(zhí)行耗時(shí)的異步操作...dispatch_async(dispatch_get_main_queue(), ^{? ? ? 回到主線(xiàn)程,執(zhí)行UI刷新操作? ? ? ? });});
延時(shí)執(zhí)行
設(shè)定好延遲的時(shí)間后,它會(huì)先執(zhí)行后邊的代碼,2秒后再調(diào)用self的run方法(并且不會(huì)卡主線(xiàn)程,在主線(xiàn)程調(diào)最后會(huì)回到主線(xiàn)程,在子線(xiàn)程調(diào)最后會(huì)回到子線(xiàn)程)
withObject:參數(shù)afterDelay:延遲的時(shí)間[selfperformSelector:@selector(run) withObject:nilafterDelay:2.0];
使用GCD函數(shù)(2秒后自動(dòng)開(kāi)啟新線(xiàn)程 執(zhí)行block中的代碼,不會(huì)卡主當(dāng)前的線(xiàn)程,在主/子線(xiàn)程調(diào)用都可以使用)
DISPATCH_TIME_NOW:現(xiàn)在開(kāi)始的意2.0*NSEC_PER_SEC:設(shè)置的秒數(shù)(直接更改數(shù)字即可)dispatch_get_main_queue():主隊(duì)列的意思dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{2秒后執(zhí)行這里的代碼... 在哪個(gè)線(xiàn)程執(zhí)行,跟隊(duì)列類(lèi)型有關(guān)? });
3.會(huì)卡住主線(xiàn)程
[NSThread sleepForTimeInterval:3]
只執(zhí)行一次
使用dispatch_once函數(shù)能保證某段代碼在程序運(yùn)行過(guò)程中只被執(zhí)行1次
在設(shè)計(jì)模式中,單例模式也會(huì)用到
staticdispatch_once_tonceToken;dispatch_once(&onceToken, ^{? ? ? 程序運(yùn)行過(guò)程中,永遠(yuǎn)只執(zhí)行1次的代碼(這里面默認(rèn)是線(xiàn)程安全的)});
隊(duì)列組
需求:1.分別異步執(zhí)行2個(gè)耗時(shí)的操作,其次,等2個(gè)異步操作都執(zhí)行完畢后,再回到主線(xiàn)程執(zhí)行操作
dispatch_group_tgroup =? dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{? ? 執(zhí)行1個(gè)耗時(shí)的異步操作});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{? ? 執(zhí)行1個(gè)耗時(shí)的異步操作});dispatch_group_notify(group, dispatch_get_main_queue(), ^{? ? 等前面的異步操作都執(zhí)行完畢后,回到主線(xiàn)程...});
GCD的創(chuàng)建和釋放
在iOS6.0之前,在GCD中每當(dāng)使用帶creat單詞的函數(shù)創(chuàng)建對(duì)象之后,都應(yīng)該對(duì)其進(jìn)行一次release操作.
在iOS6.0之后,GCD被納入到了ARC的內(nèi)存管理機(jī)制中,在使用GCD的時(shí)候我們就像對(duì)待普通OC對(duì)象一樣對(duì)待GCD,因此不再需要我們調(diào)用release方法.
GCD 的基本使用
GCD基本使用.png
1.異步函數(shù)+并發(fā)隊(duì)列
1.創(chuàng)建隊(duì)列(并發(fā)隊(duì)列)dispatch_queue_tqueue = dispatch_queue_create("com.baidu.www", DISPATCH_QUEUE_CONCURRENT);? ? ? ? 異步函數(shù)dispatch_async(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
2.異步函數(shù)+串行隊(duì)列
1.創(chuàng)建隊(duì)列(串行隊(duì)列)dispatch_queue_tqueue = dispatch_queue_create("com.baidu.www", DISPATCH_QUEUE_SERIAL);? ? ? ? 異步函數(shù)dispatch_async(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
3.同步函數(shù)+串行隊(duì)列
1.創(chuàng)建隊(duì)列(串行隊(duì)列)dispatch_queue_tqueue = dispatch_queue_create("com.baidu.www", DISPATCH_QUEUE_SERIAL);? ? ? ? 同步函數(shù)dispatch_sync(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
4.同步函數(shù)+并發(fā)隊(duì)列
//獲得全局并發(fā)隊(duì)列dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);// 同步函數(shù)dispatch_sync(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
5.異步函數(shù)+主隊(duì)列
1.獲得主隊(duì)列dispatch_queue_tqueue = dispatch_get_main_queue();? ? ? ? 異步函數(shù)dispatch_async(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
6.同步函數(shù)+主隊(duì)列
1.獲得主隊(duì)列dispatch_queue_tqueue = dispatch_get_main_queue();dispatch_sync(queue, ^{NSLog(@"1---%@",[NSThreadcurrentThread]);? ? });
4.8 NSOperation
NSOperation作用?
配合使用NSOperation 和NSOperationQueue也能實(shí)現(xiàn)多線(xiàn)程編程
NSOperation 和NSOperationoQueue實(shí)現(xiàn)多線(xiàn)程的具體步驟
步驟.png
NSOperation的子類(lèi)
NSOperation是個(gè)抽象類(lèi),并不具備封裝操作的能力捣鲸,必須使用它的子類(lèi)
子類(lèi)的方式有3中:
1.NSInvocationOperation
2.NSBlockOperation
3.自定義子類(lèi)繼承NSOperation,實(shí)現(xiàn)內(nèi)部響應(yīng)的方法
NSInvocationOperation
1.創(chuàng)建對(duì)象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
2.調(diào)用start方法開(kāi)始執(zhí)行操作
- (void)start;
一旦執(zhí)行操作,就會(huì)調(diào)用target的sel方法
默認(rèn)情況下,調(diào)用了start方法后并不會(huì)開(kāi)一條新線(xiàn)程去執(zhí)行操作,而是在當(dāng)前線(xiàn)程同步執(zhí)行操作;只有將NSOperation放到一個(gè)NSOperationQueue中,才會(huì)異步執(zhí)行操作
NSBlockOperation
1.創(chuàng)建NSBlockOperation對(duì)象
+ (id)blockOperationWithBlock:(void(^)(void))block;
通過(guò)addExecutionBlock:方法添加更多的操作
- (void)addExecutionBlock:(void(^)(void))block;
只要NSBlockOperation封裝的操作數(shù) > 1闽坡,就會(huì)異步執(zhí)行操作
NSOperationQueue作用
如果將NSOperation添加到NSOperationQueue(操作隊(duì)列)中栽惶,系統(tǒng)會(huì)自動(dòng)異步執(zhí)行NSOperationQueue中的操作
- (void)addOperation:(NSOperation*)operation;- (void)addOperationWithBlock:(void(^)(void))block;
最大并發(fā)數(shù)
同時(shí)執(zhí)行的任務(wù)數(shù)
最大并發(fā)數(shù)相關(guān)的方法
-(NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
自定義NSOperation
重寫(xiě)-(void)main方法,在里面實(shí)現(xiàn)想執(zhí)行的任務(wù)
重寫(xiě)-(void)main方法的注意點(diǎn):自動(dòng)創(chuàng)建自動(dòng)釋放池,如果是異步操作,無(wú)法訪(fǎng)問(wèn)主線(xiàn)程的自動(dòng)釋放池
4.9 RunLoop
如果沒(méi)有RunLoop,程序輸出后就退出了
intmain(intargc,char* argv[]){? ? NSLog(@"main");return0;}
如果有了RunLoop,由于main函數(shù)里面啟動(dòng)了RunLoop,所以程序并不會(huì)馬上退出,保持持續(xù)運(yùn)行狀態(tài)
intmain(intargc,char* argv[]) {BOOLrun =YES;do{//執(zhí)行各種任務(wù),處理各種事件}while(run);return0;}
main函數(shù)中的RunLoop,UIApplicationMaiin函數(shù)內(nèi)部就啟動(dòng)了一個(gè)RunLoop,所以UIApplicationMain函數(shù)一直沒(méi)有返回,保持了程序的持續(xù)運(yùn)行,這個(gè)默認(rèn)啟動(dòng)的RunLoop跟主線(xiàn)程相關(guān)聯(lián)
intmain(intargc,char* argv[]) {@autoreleasepool{returnUIApplicationMain(argc, argv,nil,NSStringFromClass([AppDelegateclass]));? ? }}
RunLoop與線(xiàn)程
1.每條線(xiàn)程都有唯一的與之對(duì)應(yīng)的RunLoop對(duì)象
2.主線(xiàn)程的RunLoop已經(jīng)自動(dòng)創(chuàng)建好了,子線(xiàn)程的RunLoop需要主動(dòng)創(chuàng)建
3.RunLoop在第一次獲取時(shí)創(chuàng)建,在線(xiàn)程結(jié)束時(shí)銷(xiāo)毀
獲得RunLoop對(duì)象
獲得RunLoop對(duì)象.png
RunLoop相關(guān)類(lèi)
RunLoop相關(guān)類(lèi).png
Core Foundation中關(guān)于RunLoop的5個(gè)類(lèi):
CFRunLoopRef:它自己,也就代表一個(gè)RunLoop對(duì)象
CFRunLoopModeRef:RunLoop的運(yùn)行模式
CFRunLoopSourceRef:事件源
CFRunLoopTimerRef:時(shí)間的觸發(fā)器
CFRunLoopbaserverRef:觀察者 監(jiān)聽(tīng)CFRunLoopRef的狀態(tài)
CFRunLoopModeRef
系統(tǒng)默認(rèn)注冊(cè)了5個(gè)Mode模式:
kCFRunLoopDefaultMode:App的默認(rèn)Mode,通常主線(xiàn)程是在這個(gè)Mode下運(yùn)行
UITrackingRunLoopMode:界面跟蹤 Mode疾嗅,用于 ScrollView 追蹤觸摸滑動(dòng)外厂,保證界面滑動(dòng)時(shí)不受其他 Mode 影響
UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode,啟動(dòng)完成后就不再使用
GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode代承,通常用不到
kCFRunLoopCommonModes: 這是一個(gè)占位用的Mode汁蝶,不是一種真正的Mode
RunLoop處理邏輯
RunLoop處理邏輯.png
1.通知觀察者,即將進(jìn)入Loop
2.通知觀察者,將要處理定時(shí)器
3.通知觀察者,將要處理非基于端口的源
4.處理非基于端口的源
5.如果有基于端口的源準(zhǔn)備好并處于等待狀態(tài),立即啟動(dòng),跳到第9步
6.通知觀察者,線(xiàn)程即將休眠
7.休眠,等待喚醒
8.通知觀察者,線(xiàn)程剛被喚醒
9.處理喚醒時(shí)收到的消息,之后跳到第2步
10.通知觀察者,即將推出Loop
RunLoop應(yīng)用
RunLoop應(yīng)用.png
RunLoop面試題
1.什么是RunLoop?
字面意思運(yùn)行循環(huán)
其實(shí)它內(nèi)部就是do-while循環(huán),這個(gè)循環(huán)內(nèi)部不斷處理各種任務(wù)(比如Source,Timer,Observer);
一個(gè)線(xiàn)程對(duì)應(yīng)一個(gè)RunLoop,主線(xiàn)程的RunLoop默認(rèn)啟動(dòng),子線(xiàn)程的RunLoop手動(dòng)啟動(dòng);
RunLoop只能選擇一個(gè)Mode啟動(dòng),如果當(dāng)前Mode中沒(méi)有任何Source,Timer,那么就直接退出RunLoop.
4.10 HTTP通信過(guò)程-請(qǐng)求/響應(yīng)
HTTP通信過(guò)程.png
HTTP協(xié)議規(guī)定:1個(gè)完整的由客戶(hù)端發(fā)給服務(wù)器的HTTP請(qǐng)求中包含以下內(nèi)容
HTTP通信過(guò)程-請(qǐng)求.png
HTTP通信-響應(yīng).png
人才濟(jì)濟(jì)的iOS開(kāi)發(fā)者,你憑什么脫穎而出论悴?
與崗位要求相去甚遠(yuǎn)掖棉,如何挑戰(zhàn)極限?
想去心怡公司膀估,如何馬到成功幔亥?
那么,你的絕招是什么呢察纯?
在這個(gè)iOS崗位供不應(yīng)求的市場(chǎng)帕棉,對(duì)iOS開(kāi)發(fā)者對(duì)要求日益增長(zhǎng),小編分享一下最近對(duì)招人心得捐寥,放出47道面試題+答案笤昨,供廣大iOS開(kāi)發(fā)者參考
底層:
1祖驱、runloop和線(xiàn)程有什么關(guān)系握恳?
2、你是否接觸過(guò)OC中的反射機(jī)制捺僻?簡(jiǎn)單聊一下概念和使用
3乡洼、objc中的類(lèi)方法和實(shí)例方法有什么本質(zhì)區(qū)別和聯(lián)系崇裁?
4、runloop的mode作用是什么束昵?
5拔稳、1runloop是什么/runloop的概念?
6锹雏、id與instanncetype?
7巴比、什么是GDB和LLDB?
8礁遵、模擬棧操作?
9轻绞、你是否接觸過(guò)OC中的反射機(jī)制?簡(jiǎn)單聊一下概念和使用?
10佣耐、ldb(gdb)常用的調(diào)試命令政勃?
11、block一般用那個(gè)關(guān)鍵字修飾兼砖,為什么奸远? 哪些情況會(huì)引起block循環(huán)引用,怎么解決
12讽挟、為什么很多內(nèi)置的類(lèi)懒叛,如TableViewController的delegate的屬性是assign不是retain?
13耽梅、ViewController的didReceiveMemoryWarning是在什么時(shí)候調(diào)用的芍瑞?默認(rèn)的操作是什么?
14褐墅、使用block時(shí)什么情況會(huì)發(fā)生引用循環(huán)拆檬,如何解決?
15妥凳、IB中User Defined Runtime Attributes如何使用竟贯?
基礎(chǔ):
16、weak和unowned?
17逝钥、什么是GDB和LLDB屑那?
18、static?關(guān)鍵字的作用:
19艘款、Objective-C如何對(duì)內(nèi)存管理的,說(shuō)說(shuō)你的看法和解決方法??
20持际、內(nèi)存管理的幾條原則時(shí)什么?按照默認(rèn)法則.那些關(guān)鍵字生成的對(duì)象需要手動(dòng)釋放?在和property結(jié)合的時(shí)候怎樣有效的避免內(nèi)存泄露?
21、NSOperation queue?
22哗咆、什么是延遲加載??
23蜘欲、BAD_ACCESS在什么情況下出現(xiàn)?
24晌柬、0x8badf00d表示是什么姥份?
25郭脂、GCD與NSOperation這兩者有什么區(qū)別?
26澈歉、單例的優(yōu)弊是什么展鸡?
27、RunLoop和線(xiàn)程的關(guān)系: 怎么讓子線(xiàn)程執(zhí)行完成任務(wù)后不銷(xiāo)毀
28埃难、nonatomic和atomic對(duì)比? 說(shuō)說(shuō)你對(duì)他們的理解莹弊。
29、兩個(gè)對(duì)象之間相互通信 有哪些通信方式
30涡尘、os的數(shù)據(jù)存儲(chǔ)有哪些方式箱硕,sqlite數(shù)據(jù)庫(kù)是否支持多個(gè)線(xiàn)程寫(xiě)入數(shù)據(jù),如果不支持怎么解決悟衩?
31剧罩、一個(gè)函數(shù)執(zhí)行10次,有二次結(jié)果不正確 八次正確座泳,你應(yīng)? 該怎么檢查該bug惠昔。
32、1-1000 個(gè)數(shù)字挑势,順序打亂镇防,又丟失了三個(gè)數(shù)字,找出丟失的三個(gè)數(shù)字潮饱。
33来氧、Object-C有私有方法嗎?私有變量呢香拉?
34啦扬、堆和棧的區(qū)別?
35凫碌、能否向編譯后得到的類(lèi)中增加實(shí)例變量扑毡?能否向運(yùn)行時(shí)創(chuàng)建的類(lèi)中添加實(shí)例變量?為什么盛险?
36瞄摊、如何用GCD同步若干個(gè)異步調(diào)用?(如根據(jù)若干個(gè)url異步加載多張圖片苦掘,然后在都下載完成后合成一張整圖)
37换帜、dispatch_barrier_async的作用是什么?
框架:
38鹤啡、第三方內(nèi)存泄漏檢測(cè)工具:MLeaksFinder原理分析?
39惯驼、逃逸閉包
40、cocoa touch框架?
網(wǎng)絡(luò):
41揉忘、HTTP協(xié)議詳解?
42跳座、談?wù)勀銓?duì)HTTP 、TCP泣矛、 IP疲眷、socket 協(xié)議的理解
測(cè)試:
43、單元測(cè)試那些事!?
44您朽、為什么使用這個(gè)單元測(cè)試呢狂丝?它給我們帶來(lái)了什么好處呢?
45哗总、單元測(cè)試的重要性:?
swift:
46几颜、swift閉包
47、swift中高階函數(shù)map用法