iOS面試題-常問題及答案

未完愈案,待更新

一、必備題

1、AFN 原理

鏈接:AFNetworking源碼——基本架構(gòu) - 簡書

2双藕、SDWebImage原理

鏈接:iOS利用SDWebImage圖片下載緩存 - 簡書

3止状、runtime

鏈接:談?wù)刬OS-runtime - 簡書

4烹棉、runloop

5、多線程

6怯疤、block 浆洗、代理

7、MVC集峦、MVVM

8伏社、KVC、KVO

以上就是面試的時(shí)候問的最多的

以下是我覺得很有用的題

二少梁、面試題

1洛口、Objective-C如何對內(nèi)存管理的?內(nèi)存管理的原則是凯沪?

1第焰、Objective-C的內(nèi)存管理主要有三種方式ARC(自動(dòng)內(nèi)存計(jì)數(shù))、MRC(手動(dòng)內(nèi)存計(jì)數(shù))妨马、autorelease(自動(dòng)釋放池)挺举。

每個(gè) 對象都有一個(gè)引用計(jì)數(shù)器杀赢,每個(gè)新對象的計(jì)數(shù)器是1丐吓,當(dāng)對象計(jì)數(shù)器減為0時(shí)蚜退,就會(huì)被銷毀帮寻。

2逛拱、內(nèi)存管理原則(配對原則):只要出現(xiàn)了new/alloc/retain,就一定配對出現(xiàn)一個(gè)release/autorelease

2月幌、談?wù)勀銓Χ嗑€程開發(fā)的理解芹壕?ios中有幾種實(shí)現(xiàn)多線程的方法淆两?

多線程:

好處:

1师崎、使用線程可以把程序中占據(jù)時(shí)間長的任務(wù)放到后臺(tái)去處理铺敌,如圖片汇歹、視頻的下載2、發(fā)揮多核處理器的優(yōu)勢偿凭,并發(fā)執(zhí)行讓系統(tǒng)運(yùn)行的更快产弹、更流暢,用戶體驗(yàn)更好

缺點(diǎn):

1弯囊、大量的線程降低代碼的可讀性

2痰哨、更多的線程需要更多的內(nèi)存空間

3、當(dāng)多個(gè)線程對同一個(gè)資源出現(xiàn)爭奪的時(shí)候要注意線程安全的問題匾嘱。

iOS有三種多線程編程的技術(shù):NSThread斤斧、NSOperation、GCD

3奄毡、談?wù)剋eek

weak表其實(shí)是一個(gè)hash表折欠,Key是所指對象的地址,Value是weak指針的地址數(shù)組吼过,weak是弱引用锐秦,所引用對象的計(jì)數(shù)器不會(huì)+1,并在引用對象被釋放的時(shí)候自動(dòng)被設(shè)置為nil。通常用于解決循環(huán)引用問題盗忱。

4酱床、 UITableview的優(yōu)化方法


5、什么是 TCP連接的三次握手

 1趟佃、建立連接時(shí)扇谣,客戶端發(fā)送SYN包到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài)闲昭,等待服務(wù)器確認(rèn)罐寨;

 2、服務(wù)器收到SYN包序矩,必須確認(rèn)客戶的SYN鸯绿,同時(shí)自己也發(fā)送一個(gè)SYN包,即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)瓶蝴;

 3毒返、客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK舷手,此包發(fā)送完畢拧簸,客戶端和服務(wù)器進(jìn)入established狀態(tài),完成三次握手男窟;

另一種白話理解:

第一次握手: 客戶端發(fā)送網(wǎng)絡(luò)包盆赤,服務(wù)端收到了。這樣服務(wù)端就能得出結(jié)論:客戶端的發(fā)送能力歉眷、服務(wù)端的接收能力是正常的弟劲。

第二次握手:服務(wù)端發(fā)包,客戶端收到了姥芥。這樣客戶端就能得出結(jié)論:服務(wù)端的接收、發(fā)送能力汇鞭,客戶端的接收凉唐、發(fā)送能力是正常的。不過此時(shí)服務(wù)器并不能確認(rèn)客戶端的接收能力是否正常霍骄。

第三次握手: 客戶端發(fā)包台囱,服務(wù)端收到了。這樣服務(wù)端就能得出結(jié)論:客戶端的接收读整、發(fā)送能力正常簿训,服務(wù)器自己的發(fā)送、接收能力也正常米间。

6强品、Socket的實(shí)現(xiàn)原理及 Socket之間是如何通信的

網(wǎng)絡(luò)上的兩個(gè)程序通過一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個(gè)連接的一端稱為一個(gè)socket屈糊。建立網(wǎng)絡(luò)通信連接至少要一對端口號(hào)(socket)的榛。socket本質(zhì)是編程接口(API),對TCP/IP的封裝逻锐,TCP/IP也要提供可供程序員做網(wǎng)絡(luò)開發(fā)所用的接口夫晌,這就是Socket編程接口

7、HTTPS實(shí)現(xiàn)過程

通信過程有四次握手

1昧诱、客戶端發(fā)送請求晓淀,服務(wù)器返回公鑰給客戶端;

2盏档、客戶端生成對稱加密秘鑰凶掰,用公鑰對其進(jìn)行加密后,返回給服務(wù)器;

3锄俄、服務(wù)器收到后局劲,利用私鑰解開得到對稱加密秘鑰,保存奶赠;

4鱼填、之后的交互都使用對稱加密后的數(shù)據(jù)進(jìn)行交互。

8毅戈、自動(dòng)釋放池底層怎么實(shí)現(xiàn)?如何工作苹丸?何時(shí)創(chuàng)建?何時(shí)銷毀苇经?

自動(dòng)釋放池以棧的形式實(shí)現(xiàn):當(dāng)你創(chuàng)建一個(gè)新的自動(dòng)釋放池時(shí)赘理,它將被添加到棧頂。當(dāng)一個(gè)對象收到發(fā)送autorelease消息時(shí),它被添加到當(dāng)前線程的處于棧頂?shù)淖詣?dòng)釋放池中,當(dāng)自動(dòng)釋放池被回收時(shí),它們從棧中被刪除,并且會(huì)給池子里面所有的對象都會(huì)做一次release操作.

1).oc是通過一種"referring counting"(引用計(jì)數(shù))的方式來管理內(nèi)存的,對象在開始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一,每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷毀.

2). NSAutoreleasePool就是用來做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不用你管的.

3). autorelease和release沒什么區(qū)別,只是引用計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減一.

10扇单、怎么保證多人開發(fā)進(jìn)行內(nèi)存泄露的檢查.

* 使用Analyze進(jìn)行代碼的靜態(tài)分析

* 為避免不必要的麻煩, 多人開發(fā)時(shí)盡量使用ARC

11商模、按鈕或者其它 UIView控件的事件傳遞的具體過程

觸摸事件的傳遞是從父控件傳遞到子控件也就是UIApplication->window->尋找處理事件最合適的view

注 意: 如果父控件不能接受觸摸事件,那么子控件就不可能接收到觸摸事件

應(yīng)用如何找到最合適的控件來處理事件蜘澜?

1).首先判斷主窗口(keyWindow)自己是否能接受觸摸事件

2).判斷觸摸點(diǎn)是否在自己身上

3).子控件數(shù)組中從后往前遍歷子控件施流,重復(fù)前面的兩個(gè)步驟(所謂從后往前遍歷子控件,就是首先查找子控件數(shù)組中最后一個(gè)元素鄙信,然后執(zhí)行1瞪醋、2步驟)

4).view,比如叫做fitView装诡,那么會(huì)把這個(gè)事件交給這個(gè)fitView银受,再遍歷這個(gè)fitView的子控件,直至沒有更合適的view為止鸦采。

5).如果沒有符合條件的子控件宾巍,那么就認(rèn)為自己最合適處理這個(gè)事件,也就是自己是最合適的view渔伯。

UIView不能接收觸摸事件的三種情況:

* 不允許交互:userInteractionEnabled = NO

* 隱藏:如果把父控件隱藏蜀漆,那么子控件也會(huì)隱藏,隱藏的控件不能接受事件

* 透明度:如果設(shè)置一個(gè)控件的透明度<0.01咱旱,會(huì)直接影響子控件的透明度确丢。alpha:0.0~0.01為透明。

注 意:默認(rèn)UIImageView不能接受觸摸事件吐限,因?yàn)椴辉试S交互鲜侥,即userInteractionEnabled = NO。所以如果希望UIImageView可以交互诸典,需要設(shè)置UIImageView的userInteractionEnabled = YES描函。

12、weak 和strong有什么區(qū)別?

其實(shí)就是弱應(yīng)用和強(qiáng)引用的區(qū)別舀寓,強(qiáng)引用持有對象胆数,而弱引用不持有對象,因?yàn)閟trong的對象會(huì)使retainCount+1互墓,而weak的并不會(huì)必尼。

13、把程序自己關(guān)掉和程序進(jìn)入后臺(tái),遠(yuǎn)程推送的區(qū)別

1). 關(guān)掉后不執(zhí)行任何代碼, 不能處理事件

2). 應(yīng)用程序進(jìn)入后臺(tái)狀態(tài)不久后轉(zhuǎn)入掛起狀態(tài)篡撵。在這種狀態(tài)下判莉,應(yīng)用程序不執(zhí)行任何代碼,并有可能在任意時(shí)候從內(nèi)存中刪除育谬。只有當(dāng)用戶再次運(yùn)行此應(yīng)用券盅,應(yīng)用才會(huì)從掛起狀態(tài)喚醒,代碼得以繼續(xù)執(zhí)行

3).或者進(jìn)入后臺(tái)時(shí)開啟多任務(wù)狀態(tài)膛檀,保留在內(nèi)存中锰镀,這樣就可以執(zhí)行系統(tǒng)允許的動(dòng)作

4).遠(yuǎn)程推送是由遠(yuǎn)程服務(wù)器上的程序發(fā)送到APNS,再由APNS把消息推送至設(shè)備上的程序,當(dāng)應(yīng)用程序收到推送的消息會(huì)自動(dòng)調(diào)用特定的方法執(zhí)行事先寫好的代碼

14、談?wù)剅unloop

? ? 1咖刃、 運(yùn)行循環(huán)是與線程相關(guān)的基礎(chǔ)的一部分互站。運(yùn)行循環(huán)是一個(gè)事件處理循環(huán),用于調(diào)度工作并協(xié)調(diào)事件的接收僵缺。運(yùn)行循環(huán)的目的是在有工作要做時(shí)保持線程忙,當(dāng)沒有線程時(shí)將線程放在睡眠中

? ? 2踩叭、底層就是do-while循環(huán)

? ? 3磕潮、runloop是來調(diào)度線程的,當(dāng)線程的runloop被開啟后容贝,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài)自脯,有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)

15、runloop和線程有什么關(guān)系斤富?

* 每條線程都有唯一的一個(gè)RunLoop對象與之對應(yīng)的

* 主線程的RunLoop是自動(dòng)創(chuàng)建并啟動(dòng)

* 子線程的RunLoop需要手動(dòng)啟動(dòng),子線程runloop是懶加載用到的時(shí)候獲取

* 子線程的RunLoop創(chuàng)建步驟如下:

? ? * 獲得RunLoop對象后要調(diào)用run方法來啟動(dòng)一個(gè)運(yùn)行循環(huán)

// 啟動(dòng)RunLoop

[[NSRunLoop currentRunLoop] run];

? ? * RunLoop的其他啟動(dòng)方法

// 第一個(gè)參數(shù):指定運(yùn)行模式

// 第二個(gè)參數(shù):指定RunLoop的過期時(shí)間膏潮,即:到了這個(gè)時(shí)間后RunLoop就失效了

[[NSRunLoop currentRunLoop] runMode:kCFRunLoopDefaultMode beforeDate:[NSDate distantFuture]];

* RunLoop是來管理線程的,當(dāng)線程的RunLoop被開啟后满力,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài)焕参,有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)。

* RunLoop在第一次獲取時(shí)被創(chuàng)建油额,在線程結(jié)束時(shí)被銷毀叠纷。

16、runloop是來做什么的潦嘶?runloop和線程有什么關(guān)系涩嚣?主線程默認(rèn)開啟了runloop么?子線程呢?

runloop的mode是用來做什么的航厚?有幾種mode顷歌?

為什么把NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)以后,滑動(dòng)scrollview的時(shí)候NSTimer卻不動(dòng)了幔睬?

答:1).runloop是來管理線程的眯漩,當(dāng)線程的runloop被開啟后,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài)溪窒,有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)坤塞。runloop和線程有什么關(guān)系,看問題15.主線程默認(rèn)開啟runloop,子線程需要自己去獲取.

2).model:是runloop里面的模式澈蚌,不同的模式下的runloop處理的事件和消息有一定的差別摹芙。

系統(tǒng)默認(rèn)注冊了5個(gè)Mode:

(1)kCFRunLoopDefaultMode: App的默認(rèn) Mode,通常主線程是在這個(gè) Mode 下運(yùn)行的宛瞄。

(2)UITrackingRunLoopMode: 界面跟蹤 Mode浮禾,用于 ScrollView 追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他 Mode 影響份汗。

(3)UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode盈电,啟動(dòng)完成后就不再使用。

(4)GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode杯活,通常用不到匆帚。

(5)kCFRunLoopCommonModes: 這是一個(gè)占位的 Mode,沒有實(shí)際作用旁钧。

3).nstime對象是在 NSDefaultRunLoopMode下面調(diào)用消息的吸重,但是當(dāng)我們滑動(dòng)scrollview的時(shí)候,NSDefaultRunLoopMode模式就自動(dòng)切換到UITrackingRunLoopMode模式下面歪今,卻不可以繼續(xù)響應(yīng)nstime發(fā)送的消息嚎幸。所以如果想在滑動(dòng)scrollview的情況下面還調(diào)用nstime的消息,我們可以把nsrunloop的模式更改為NSRunLoopCommonModes

17寄猩、NSString為什么要用copy關(guān)鍵字嫉晶,如果用strong會(huì)有什么問題?(注意:這里沒有說用strong就一定不行田篇。使用copy和strong是看情況而定的

經(jīng)常使用copy關(guān)鍵字原因:

1).因?yàn)楦割愔羔樋梢灾赶蜃宇悓ο?使用copy的目的是為了讓本對象的屬性不受外界影響,使用copy無論給我傳入是一個(gè)可變對象還是不可對象,我本身持有的就是一個(gè)不可變的副本.

如果改用strong關(guān)鍵字替废,可能造成什么問題?

2).如果我們使用是strong,那么這個(gè)屬性就有可能指向一個(gè)可變對象,如果這個(gè)可變對象在外部被修改了,那么會(huì)影響該屬性.

舉例說明:

定義一個(gè)以 strong 修飾的 array:

@property (nonatomic ,readwrite, strong)NSArray *array;

然后進(jìn)行下面的操作:

NSArray *array = @[ @1, @2, @3, @4 ];

NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];

self.array = mutableArray;

[mutableArray removeAllObjects];

NSLog(@"%@",self.array);

[mutableArray addObjectsFromArray:array];

self.array = [mutableArray copy];

[mutableArray removeAllObjects];

NSLog(@"%@",self.array);

打印結(jié)果如下所示:

19:10:32.523 XXArrayCopyDmo[10681:713670] ()

19:10:32.524 XXArrayCopyDmo[10681:713670] (1,2,3,4)


18泊柬、 UITableview的優(yōu)化方法


19舶担、有沒有用過運(yùn)行時(shí),用它都能做什么彬呻?(交換方法衣陶,創(chuàng)建類柄瑰,給新創(chuàng)建的類增加方法,改變isa指針)


20剪况、以+scheduledTimerWithTimeInterval...的方式觸發(fā)的 timer教沾,在滑動(dòng)頁面上的列表時(shí),timer會(huì)暫定回調(diào)译断,為什么授翻?如何解決?


這里強(qiáng)調(diào)一點(diǎn):在主線程中以+scheduledTimerWithTimeInterval...的方式觸發(fā)的timer 默認(rèn)是運(yùn)行在 NSDefaultRunLoopMode模式下的孙咪,當(dāng)滑動(dòng)頁面上的列表時(shí)堪唐,進(jìn)入了 UITrackingRunLoopMode模式,這時(shí)候 timer 就會(huì)停止翎蹈』床ぃ可以修改 timer 的運(yùn)行模式為 NSRunLoopCommonModes,這樣定時(shí)器就可以一直運(yùn)行了荤堪。

以下是我的補(bǔ)充:

在子線程中通過 scheduledTimerWithTimeInterval:...方法來構(gòu)建

NSTimer方法內(nèi)部已經(jīng)創(chuàng)建NSTimer 對象 合陵,并加入到 RunLoop 中 , 運(yùn)行模式為NSDefaultRunLoopMode澄阳。

由于 Mode 有 timer 對象拥知,所以 RunLoop 就開始監(jiān)聽定時(shí)器事件了,從而開始進(jìn)入運(yùn)行循環(huán)碎赢。

這個(gè)方法僅僅是創(chuàng)建 RunLoop 對象低剔,并不會(huì)主動(dòng)啟動(dòng) RunLoop,需要再調(diào)用 run方法來啟動(dòng)

如果在主線程中通過 scheduledTimerWithTimeInterval:...方法來構(gòu)

建 NSTimer肮塞,就不需要主動(dòng)啟動(dòng) RunLoop 對象襟齿,因?yàn)橹骶€程的 RunLoop 對象在程序運(yùn)行起來就已經(jīng)被啟動(dòng)了


// userInfo 參數(shù):用來給 NSTimer 的

userInfo屬性賦值,userInfo是只讀的峦嗤,只能在構(gòu)建 NSTimer對象

時(shí)賦值

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self

selector:@selector(run:)? ? userInfo:@"ya了個(gè)hoo"

repeats:YES];


//scheduledTimer...方法創(chuàng)建出來 NSTimer雖然已經(jīng)指定了默認(rèn)模

式,但是【允許你修改模式】

[[NSRunLoop currentRunLoop] addTimer:timer

forMode:NSRunLoopCommonModes];


// 【僅在子線程】需要手動(dòng)啟動(dòng) RunLoop對象屋摔,進(jìn)入運(yùn)行循環(huán)

[[NSRunLoop currentRunLoop] run];


21烁设、以下代碼運(yùn)行結(jié)果如何?

- (void)viewDidLoad

{

[super viewDidLoad];

NSLog(@"1");

dispatch_sync(dispatch_get_main_queue(), ^{

NSLog(@"2");

});

NSLog(@"3");

}

答案:輸出1? ? 原因:主線程死鎖


22钓试、 POST方法和 GET方法有那些區(qū)別?

1装黑、url可見性:get,參數(shù)url可見弓熏;post恋谭,url參數(shù)不可見 。2挽鞠、數(shù)據(jù)傳輸上:get疚颊,通過拼接url進(jìn)行傳遞參數(shù)狈孔;post,通過body體傳輸參數(shù)材义。? ? 3均抽、緩存性:get請求是可以緩存的post請求不可以緩存 。4其掂、后退頁面的反應(yīng)get請求頁面后退時(shí)油挥,不產(chǎn)生影響post請求頁面后退時(shí),會(huì)重新提交請求款熬。? ? 5深寥、傳輸數(shù)據(jù)的大小get一般傳輸數(shù)據(jù)大小不超過2k-4k(根據(jù)瀏覽器不同,限制不一樣贤牛,但相差不大)post請求傳輸數(shù)據(jù)的大小根據(jù)php.ini 配置文件設(shè)定惋鹅,也可以無限大。6盔夜、安全性這個(gè)也是最不好分析的负饲,原則上post肯定要比get安全,畢竟傳輸參數(shù)時(shí)url不可見喂链,但也擋不住部分人閑的沒事在那抓包玩返十。安全性個(gè)人覺得是沒多大區(qū)別的,防君子不防小人就是這個(gè)道理椭微。對傳遞的參數(shù)進(jìn)行加密洞坑,其實(shí)都一樣。


GET和POST還有一個(gè)重大區(qū)別

簡單的說:

GET產(chǎn)生一個(gè)TCP數(shù)據(jù)包蝇率;POST產(chǎn)生兩個(gè)TCP數(shù)據(jù)包迟杂。

長的說:

對于GET方式的請求,瀏覽器會(huì)把http header和data一并發(fā)送出去本慕,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù))排拷;

而對于POST,瀏覽器先發(fā)送header锅尘,服務(wù)器響應(yīng)100 continue监氢,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))藤违。

注意 :并不是所有瀏覽器都會(huì)在POST中發(fā)送兩次包浪腐,F(xiàn)irefox就只發(fā)送一次。


23、使用 block時(shí)什么情況會(huì)發(fā)生引用循環(huán),如何解決恩掷?

一個(gè)對象中強(qiáng)引用了block,在block中又強(qiáng)引用了該對象特漩,即雙向引用吧雹,就會(huì)發(fā)生循環(huán)引用。

解決方法是將該對象使用__weak或者_(dá)_block修飾符修飾之后再在block中使用拾稳。

id __weak weakSelf = self; 或者 __weak __typeof(self)weakSelf = self;. 該方法可以設(shè)置宏

id __block weakSelf = self;

或者將其中一方強(qiáng)制制空 xxx = nil吮炕。

檢測代碼中是否存在循環(huán)引用問題,可使用 Facebook 開源的一個(gè)檢測工具 FBRetainCycleDetector或者在類中重寫delloc方法访得,只要每個(gè)類調(diào)用了delloc即釋放了 龙亲。

24、沙盒目錄結(jié)構(gòu)是怎樣的悍抑?各自用于那些場景鳄炉?

Application:存放程序源文件,上架前經(jīng)過數(shù)字簽名搜骡,上架后不可修改

Documents:常用目錄拂盯,iCloud 備份目錄,存放數(shù)據(jù)

Library

1).Caches:存放體積大又不需要備份的數(shù)據(jù)

2).Preference:設(shè)置目錄记靡,iCloud 會(huì)備份設(shè)置信息

3).tmp:存放臨時(shí)文件谈竿,不會(huì)被備份,而且這個(gè)文件下的數(shù)據(jù)有可能隨時(shí)被清除的可能


25摸吠、控制器的生命周期

就是問的 view 的生命周期空凸,下面已經(jīng)按方法執(zhí)行順序進(jìn)行了排序

// 自定義控制器 view,這個(gè)方法只有實(shí)現(xiàn)了才會(huì)執(zhí)行

- (void)loadView

{

self.view = [[UIView alloc] init];

self.view.backgroundColor = [UIColor orangeColor];

}

// view 是懶加載寸痢,只要 view 加載完畢就調(diào)用這個(gè)方法

- (void)viewDidLoad

{

[super viewDidLoad];

}

// view 即將顯示

- (void)viewWillAppear:(BOOL)animated{

[super viewWillAppear:animated];

}

// view 即將開始布局子控件

- (void)viewWillLayoutSubviews{

[super viewWillLayoutSubviews];

}

// view 已經(jīng)完成子控件的布局

- (void)viewDidLayoutSubviews{

[super viewDidLayoutSubviews];

}

// view 已經(jīng)出現(xiàn)

- (void)viewDidAppear:(BOOL)animated

{

? ? [super viewDidAppear:animated];

}

// view 即將消失

- (void)viewWillDisappear:(BOOL)animated{

? ? [super viewWillDisappear:animated];

}

// view 已經(jīng)消失

- (void)viewDidDisappear:(BOOL)animated{

[super viewDidDisappear:animated];

}

// 收到內(nèi)存警告

- (void)didReceiveMemoryWarning{

[super didReceiveMemoryWarning];

}

// 方法已過期呀洲,即將銷毀 view

- (void)viewWillUnload{

}

// 方法已過期,已經(jīng)銷毀 view

- (void)viewDidUnload{

}

但是我們最長常用方法:

viewDidLoad

viewWillAppear

viewWillDisappear


25啼止、ARC是為了解決什么問題誕生的道逗?

首先解釋 ARC: automatic reference counting 自動(dòng)引用計(jì)數(shù)

MRC 的缺點(diǎn):

在 MRC 時(shí)代當(dāng)我們要釋放一個(gè)堆內(nèi)存時(shí),首先要確定指向這個(gè)堆空間的指針都被release 了

釋放指針指向的堆空間献烦,首先要確定哪些指針指向同一個(gè)堆滓窍,這些指針只能釋放一次(MRC 下即誰創(chuàng)建,誰釋放巩那,避免重復(fù)釋放)

模塊化操作時(shí)吏夯,對象可能被多個(gè)模塊創(chuàng)建和使用,不能確定最后由誰去釋放

多線程操作時(shí)拢操,不確定哪個(gè)線程最后使用完畢

綜上所述锦亦,MRC 有諸多缺點(diǎn)舶替,很容易造成內(nèi)存泄露和壞內(nèi)存的問題令境,這時(shí)蘋果為盡量解決這個(gè)問題,從而誕生了 ARC


26顾瞪、ARC下還會(huì)存在內(nèi)存泄露嗎舔庶?

循環(huán)引用會(huì)導(dǎo)致內(nèi)存泄露.

Objective-C 對象與 CoreFoundation 對象進(jìn)行橋接的時(shí)候如果管理不當(dāng)也會(huì)造成內(nèi)存泄露.

CoreFoundation 中的對象不受 ARC 管理抛蚁,需要開發(fā)者手動(dòng)釋放

27、什么情況使用 weak關(guān)鍵字惕橙,相比 assign有什么不同瞧甩?

首先明白什么情況使用 weak關(guān)鍵字?

1.在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用 weak 來解決,比如:delegate 代理屬性弥鹦,代理屬性也可使用 assign

2.自身已經(jīng)對它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次,此時(shí)也會(huì)使用 weak,自定義

3.IBOutlet 控件屬性一般也使用 weak肚逸;當(dāng)然,也可以使用 strong彬坏,但是建議使用 weak

weak 和 assign 的不同點(diǎn)

weak 策略在屬性所指的對象遭到摧毀時(shí)朦促,系統(tǒng)會(huì)將 weak 修飾的屬性對象的指針指向 nil,在 OC 給 nil 發(fā)消息是不會(huì)有什么問題的栓始;如果使用 assign 策略在屬性所指的對象遭到摧毀時(shí)务冕,屬性對象指針還指向原來的對象,由于對象已經(jīng)被銷毀幻赚,這時(shí)候就產(chǎn)生了野指針禀忆,如果這時(shí)候在給此對象發(fā)送消息,很容造成程序奔潰

assigin 可以用于修飾非 OC 對象,而 weak 必須用于 OC 對象


28落恼、+(void)load; +(void)initialize;有什么用處箩退?

+(void)load;

當(dāng)類對象被引入項(xiàng)目時(shí), runtime 會(huì)向每一個(gè)類對象發(fā)送 load 消息。

在main函數(shù)調(diào)用前,+(void)load就已經(jīng)調(diào)用完了领跛。load 方法會(huì)在每一個(gè)類甚至分類被引入時(shí)僅調(diào)用一次,調(diào)用的順序:父類優(yōu)先于子類, 子類優(yōu)先于分類乏德。

由于 load 方法會(huì)在類被 import 時(shí)調(diào)用一次,而這時(shí)往往是改變類的行為的最佳時(shí)機(jī),在這里可以使用例如 method swizlling 來修改原有的方法吠昭。

load 方法不會(huì)被類自動(dòng)繼承喊括。

+(void)initialize;

也是在第一次使用這個(gè)類的時(shí)候會(huì)調(diào)用這個(gè)方法,也就是說 initialize 也是懶加載

總結(jié):

在 Objective-C 中矢棚,runtime 會(huì)自動(dòng)調(diào)用每個(gè)類的這兩個(gè)方法

1.+load 會(huì)在類初始加載時(shí)調(diào)用

2.+initialize 會(huì)在第一次調(diào)用類的類方法或?qū)嵗椒ㄖ氨徽{(diào)用

這兩個(gè)方法是可選的郑什,且只有在實(shí)現(xiàn)了它們時(shí)才會(huì)被調(diào)用

兩者的共同點(diǎn):兩個(gè)方法都只會(huì)被調(diào)用一次

29、Foundation對象與 Core Foundation對象有什么區(qū)別

Foundation 框架是使用 OC 實(shí)現(xiàn)的蒲肋,Core Foundation 是使用 C 實(shí)現(xiàn)的蘑拯。

30、UIView 和CALayer的區(qū)別兜粘?

1申窘、UIView可以響應(yīng)事件,CALayer不可以孔轴,因?yàn)樗麄兝^承不同剃法,UIView繼承UIResponder,CALayer繼承NSObject.

2路鹰、UIView像是一個(gè)CALayer的管理器贷洲,訪問它的跟繪圖和跟坐標(biāo)有關(guān)的屬性收厨,例如frame,bounds等等优构,實(shí)際上內(nèi)部都是在訪問它所包含的CALayer的相關(guān)屬性诵叁。

3、CALayer側(cè)重動(dòng)畫钦椭,UIView顯示及事件響應(yīng)

鏈接:詳解 CALayer 和 UIView 的區(qū)別和聯(lián)系 - CocoaChina_讓移動(dòng)開發(fā)更簡單


31拧额、Category 有什么好處?為什么不能擴(kuò)張屬性彪腔?

答:好處:

1).比如一個(gè)類功能太龐大势腮,可以使用category進(jìn)行分散

2).創(chuàng)建私有方法的前向引用

-例如Person類有一個(gè)私有方法

-(void)processStr:(NSString*)str;

在viewDidLoad方法中想要使用Person的這個(gè)方法

Person* p = [[Person alloc] init];

[p precoessStr:@"str"];

這樣編譯不能通過,如果給Person添加了一個(gè)分類漫仆,并且在分類中聲明這個(gè)方法捎拯,再在viewDidLoad方法的文件中包含這個(gè)分類,那么就不會(huì)報(bào)錯(cuò)盲厌,可以正常運(yùn)行了署照。

3).添加非正式協(xié)議

正式協(xié)議需要用@protocol,@required吗浩,

@optional建芙,@delegate來規(guī)范書寫方式,而非正式協(xié)議則不需要懂扼,只要相應(yīng)的delegate類直接實(shí)現(xiàn)就可以禁荸。但是category僅限于NSObject類的分類,不能用它的子類實(shí)現(xiàn)非正式協(xié)議

如:NSObject+Test分類

-(NSString)inputStr:(NSString)str;這個(gè)方法要么在NSObject+Test.m文件中實(shí)現(xiàn)阀湿,要么在Person.m文件中實(shí)現(xiàn)

//NSObject+Test.h#import<Foundation/Foundation.h>@interfaceNSObject(Test)-(NSString*)inputStr:(NSString*)str;@end//NSObject+Test.m文件#import"NSObject+test.h"@implementationNSObject(test)@end

Person類

//Person.h文件

#import<Foundation/Foundation.h>

#import"NSObject+Test.h"

@interfacePerson:NSString

@end

//Person.m文件

#import"Person.h"

@implementationPerson

-(NSString*)inputStr:(NSString*)str{

if([str isEqualToString:@"wdc"])

{

? ? ? ? return@"ldy";

? }

return@"error";

}

@end

在viewcontroller中

- (void)viewDidLoad {

? ? [superviewDidLoad];

? Person* p = [[Person alloc] init];

NSString* str = [p inputyouName:@"wdc"];

NSLog(@"%@",str);}

輸出:ldy

不能擴(kuò)展原因請參考:探究iOS分類(category)為什么不能直接添加屬性 - lixuezhi - CSDN博客

32赶熟、簡述NotificationCenter、KVC陷嘴、KVO映砖、Delegate?并說明它們之間的區(qū)別?

Notification是觀察者模式的實(shí)現(xiàn),KVO是觀察者模式的OB-C底層實(shí)現(xiàn)。

NOtification通過Notifydcation addobserver和remove observer工作灾挨。

KVO是鍵值監(jiān)聽,鍵值觀察機(jī)制,提供了觀察某一屬性變化的方法

KVC是鍵值編碼,是一種間接訪問對象的屬性,使用字符串來標(biāo)示屬性(例如:setValue:forKey:) Delegate:把某個(gè)對象要做的事情委托給別的對象去做邑退。那么別的對象就是這個(gè)對象的代理,代替它來打理要做的事。反映到程序中,首先要明確一個(gè)對象的委托方是哪個(gè)對象,委托所做的內(nèi)容是什么劳澄。

33地技、數(shù)據(jù)持久化存儲(chǔ)方式有哪些?以及特點(diǎn)秒拔?

1).plist 屬性列表 最外層只能存儲(chǔ)數(shù)組字典 里面只能存儲(chǔ) bool NSNumber String Data Date

2).NSUserDefault 最終也是保存成plist 系統(tǒng)封裝了保存的路徑 保存的方法

3).歸檔 可以對保存數(shù)據(jù)的文件 進(jìn)行加密

4).sqlite? 關(guān)系型數(shù)據(jù)庫 以表的形式存儲(chǔ)? FMDB是對 OC中 sqlite操作封裝 的第三方庫

5).coreData 是蘋果封裝的 對文件操作的框架 可以 以對象的形式存儲(chǔ) 底層數(shù)據(jù)文件可以是sqlite類型 也可以是XML JSON …


34莫矗、如何對定位和分析項(xiàng)?中影響性能的地方?以及如何進(jìn)行性能優(yōu)化? 定位?法:

instruments? 在iOS上進(jìn)?性能分析的時(shí)候,?先考慮借助instruments這個(gè)利器分析出問題出在哪,不要憑空想象趣苏,不然你可能把精力花在了1%的問題上,最后發(fā)現(xiàn)其實(shí)啥都沒優(yōu)化梯轻,比如要查看程序哪些部分最耗時(shí)食磕,可以使用Time Profiler,要查看內(nèi)存是否泄漏了喳挑,可以使用Leaks等彬伦。關(guān)于instruments網(wǎng)上有很多資料料,作為一個(gè)合格iOS開發(fā)者伊诵,熟悉這個(gè)工具還是很有必要的单绑。

優(yōu)化建議:

1.?ARC管理理內(nèi)存

* ARC(Automatic Reference Counting, 自動(dòng)引用計(jì)數(shù))和iOS5?一起發(fā)布,它避免了 最常見的也就是經(jīng)常是由于我們忘記釋放內(nèi)存所造成的內(nèi)存泄露露曹宴。它?動(dòng)為你管理理 retain和release的過程搂橙,所以你就不必去?動(dòng)?預(yù)了。下面是你會(huì)經(jīng)常?來去創(chuàng)建一 個(gè)View的代碼段: UIView *view = [[UIView alloc] init];

* // ...

* [self.view addSubview:view];

* [view release];

* 忘掉代碼段結(jié)尾的release簡直像記得吃飯一樣簡單笛坦。而ARC會(huì)自動(dòng)在底層為你做這 些工作区转。除了幫你避免內(nèi)存泄露,ARC還可以幫你提高性能版扩,它能保證釋放掉不再需要的對象的內(nèi)存废离。

3.盡量量把views設(shè)置為完全不不透明

* 如果你有透明的Views你應(yīng)該設(shè)置它們的opaque(不透明)屬性為YES。例例如?個(gè)黑色半透明的可以設(shè)置為一個(gè)灰色不透明的View替代.原因是這會(huì)使系統(tǒng)?一個(gè)最優(yōu)的方式渲染這些views礁芦。這個(gè)簡單的屬性在IB或者代碼?都可以設(shè)定蜻韭。

* Apple的文檔對于為圖片設(shè)置透明屬性的描述是:

* (opaque)這個(gè)屬性給渲染系統(tǒng)提供了一個(gè)如何處理理這個(gè)view的提示。如果設(shè)為 YES柿扣, 渲染系統(tǒng)就認(rèn)為這個(gè)view是完全不透明的肖方,這使得渲染系統(tǒng)優(yōu)化一些渲染過程和提高性能。如果設(shè)置為NO未状,渲染系統(tǒng)正常地和其它內(nèi)容組成這個(gè)View窥妇。默認(rèn)值是 YES。

* 在相對?較靜止的畫面中娩践,設(shè)置這個(gè)屬性不會(huì)有太大影響活翩。然而當(dāng)這個(gè)view嵌在 scroll view里邊,或者是一個(gè)復(fù)雜動(dòng)畫的一部分翻伺,不設(shè)置這個(gè)屬性的話會(huì)在很?程度上影響app的性能材泄。

* 換種說法,?家可能更好理解:只要一個(gè)視圖的不透明度小于1,就會(huì)導(dǎo)致 blending.blending操作在iOS的圖形處理器(GPU)中完成的,blending主要指的是混合像素顏色的計(jì)算吨岭。舉個(gè)例子,我們把兩個(gè)圖層疊加在一起,如果第一個(gè)圖層的有透明效果,則最終像素的顏色計(jì)算需要將第二個(gè)圖層也考慮進(jìn)來拉宗。這?過程即為Blending。為什么Blending會(huì)導(dǎo)致性能的損失?原因是很直觀的,如果一個(gè)圖層是完全不透明的,則系統(tǒng)直接顯示該圖層的顏色即可。?如果圖層是帶透明效果的,則會(huì)引入更多的計(jì)算,因?yàn)樾枰严旅娴膱D層也包括進(jìn)來,進(jìn)行混合后顏?的計(jì)算旦事。

4. 避免過于龐?大的XIB

* iOS5中加入的Storyboards正在快速取代XIB魁巩。然而XIB在一些場景中仍然很有用。?如你的app需要適應(yīng)iOS5之前的設(shè)備姐浮,或者你有?個(gè)自定義的可重?的view,你就不可避免地要用到他們谷遂。

* 如果你不得不XIB的話,使他們盡量簡單卖鲤。嘗試為每個(gè)Controller配置?一個(gè)單獨(dú)的 XIB肾扰,盡可能把一個(gè)ViewController的view層次結(jié)構(gòu)分散到單獨(dú)的XIB中去。

* 需要注意的是蛋逾,當(dāng)你加載一個(gè)XIB的時(shí)候所有內(nèi)容都被放在了內(nèi)存里里集晚,包括任何圖片。如果有一個(gè)不會(huì)即刻用到的view区匣,你這就是在浪費(fèi)寶貴的內(nèi)存資源了偷拔。 Storyboards就是另一碼事兒了,storyboard僅在需要時(shí)實(shí)例例化一個(gè)viewcontroller.

* 當(dāng)你加載?個(gè)引用了了圖片或者聲音資源的nib時(shí)亏钩,nib加載代碼會(huì)把圖?片和聲音文件寫進(jìn)內(nèi)存条摸。在OS X中,圖片和聲音資源被緩存在named cache中以便將來用到時(shí)獲取铸屉。在iOS中钉蒲,僅圖片資源會(huì)被存進(jìn)named caches。取決于你所在的平臺(tái)彻坛,使?用 NSImage 或UIImage 的imageNamed:方法來獲取圖片資源顷啼。

5. 不要阻塞主線程

* 永遠(yuǎn)不要使主線程承擔(dān)過多。因?yàn)閁IKit在主線程上做所有工作昌屉,渲染钙蒙,管理理觸摸反 應(yīng)回應(yīng)輸入等都需要在它上面完成。一直使用主線程的風(fēng)險(xiǎn)就是如果你的代碼真的block了主線程间驮,你的app會(huì)失去反應(yīng)

* 大部分阻礙主進(jìn)程的情形是你的app在做一些牽涉到讀寫外部資源的I/O操作躬厌,比如 存儲(chǔ)或者網(wǎng)絡(luò)【好保或者使用像 AFNetworking這樣的框架來異步地做這些操作扛施。如果你需要做其它類型的需要耗費(fèi)巨?資源的操作(?如時(shí)間敏感的計(jì)算或者存儲(chǔ)讀寫)那就用 Grand Central Dispatch,或者 NSOperation 和 NSOperationQueues.你可以使用NSURLConnection異步地做?絡(luò)操作: + (void)sendAsynchronousRequest: (NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler

6. 在ImageViews中調(diào)整圖片大小

* 如果要在UIImageView中顯示一個(gè)來自bundle的圖片屹篓,你應(yīng)保證圖片的?小和


UIImageView的?小相同疙渣。在運(yùn)行中縮放圖片是很耗費(fèi)資源的,特別是UIImageView 嵌套在UIScrollView中的情況下堆巧。

* 如果圖片是從遠(yuǎn)端服務(wù)加載的你不能控制圖?大?妄荔,比如在下載前調(diào)整到合適?小 的話泼菌,你可以在下載完成后,最好是用background thread啦租,縮放一次哗伯,然后在 UIImageView中使用縮放后的圖片。

7. 選擇正確的Collection 學(xué)會(huì)選擇對業(yè)務(wù)場景最合適的類或者對象是寫出能效?高的代碼的基礎(chǔ)篷角。當(dāng)處理理 collections時(shí)這句話尤其正確焊刹。

Apple有?一個(gè) Collections Programming Topics 的文檔詳盡介紹了可用的classes間 的差別和你該在哪些場景中使用它們。這對于任何使用collections的人來說是一個(gè)必 讀的文檔内地。

呵呵,我就知道你因?yàn)樘L沒看...這是一些常見collection的總結(jié):

* Arrays: 有序的一組值赋除。使用index來lookup很快阱缓,使用value lookup很慢, 插?/刪 除很慢举农。

* Dictionaries: 存儲(chǔ)鍵值對荆针。 ?鍵來查找比較快。

* Sets: 無序的?組值颁糟。用值來查找很快航背,插入/刪除很快。

8. 打開gzip壓縮

* ?量app依賴于遠(yuǎn)端資源和第三?API棱貌,你可能會(huì)開發(fā)一個(gè)需要從遠(yuǎn)端下載XML, JSON, HTML或者其它格式的app玖媚。

* 問題是我們的目標(biāo)是移動(dòng)設(shè)備,因此你就不能指望?絡(luò)狀況有多好婚脱。一個(gè)?戶現(xiàn)在還在edge網(wǎng)絡(luò)今魔,下一分鐘可能就切換到了了3G。不論什么場景障贸,你肯定不想讓你的?戶等太長時(shí)間错森。

* 減?文檔的一個(gè)方式就是在服務(wù)端和你的app中打開gzip。這對于文字這種能有更?壓縮率的數(shù)據(jù)來說會(huì)有更顯著的效用篮洁。好消息是涩维,iOS已經(jīng)在NSURLConnection中默 認(rèn)支持了gzip壓縮,當(dāng)然AFNetworking這些基于它的框架亦然袁波。像Google App Engine這些云服務(wù)提供者也已經(jīng)?支持了了壓縮輸出瓦阐。


35、iOS app啟動(dòng)如何優(yōu)化?

1. 查看啟動(dòng)時(shí)間篷牌,對這塊優(yōu)化垄分。通過在 Xcode 中 Edit scheme -> Run -> Auguments 將環(huán)境變量量 DYLD_PRINT_STATISTICS 設(shè)為 1,在控制臺(tái)看到main()函數(shù)之前的啟動(dòng)時(shí)間。

2. 分解優(yōu)化目標(biāo)分步達(dá)到優(yōu)化?的

1). 耗時(shí)操作異步處理

2). 如果啟動(dòng)流程依賴網(wǎng)絡(luò)請求回來才能繼續(xù),那么需要考慮網(wǎng)絡(luò)極差情況下的啟動(dòng)速度

3). 如果APP有l(wèi)oading廣告頁并且對分辨率的要求較?,請嘗試做緩存吧

4). 主?面Controller中的viewDidLoad和viewWillAppear?法中盡量少做事情

5). 排查清理項(xiàng)目中未使用到的靜態(tài)類庫以及Framework娃磺,因?yàn)樵诰幾g階段系統(tǒng)會(huì)把靜態(tài)類庫加載到內(nèi)存里

6). 刪減合并?一些OC類,刪減沒有用到或者可以不用的靜態(tài)變量薄湿、方法等

7). 輕量化+load方法中的內(nèi)容,可延遲到+initialize中,因?yàn)閘oad在mian()函數(shù)前已經(jīng)加載過了,runtime機(jī)制


36豺瘤、談?wù)勀銓Χ嗑€程開發(fā)的理理解?ios中有幾種實(shí)現(xiàn)多線程的方法?

答案:

好處:

1.使?用線程可以把占據(jù)時(shí)間?的程序中的任務(wù)放到后臺(tái)去處理

2.?戶界面可以更加吸引人吆倦,比如用戶點(diǎn)擊了一個(gè)按鈕去觸發(fā)某些事件的處理, 可以彈出一個(gè)進(jìn)度條來顯示處理的進(jìn)度

3.程序的運(yùn)行速度可能加快

4·在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入坐求、文件讀寫和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等蚕泽,線程就比較有 用了。

缺點(diǎn):

1.如果有?量的線程,會(huì)影響性能,因?yàn)椴僮飨到y(tǒng)需要在它們之間切換桥嗤。創(chuàng)建更多的線程需要更更多的內(nèi)存空間须妻。

3.線程的中?止需要考慮其對程序運(yùn)?行行的影響。

4.通常塊模型數(shù)據(jù)是在多個(gè)線程間共享的泛领,需要防?止線程死鎖情況的發(fā)?生荒吏。 實(shí)現(xiàn)多線程的?方法:

37、NSOPrationQueue 與GCD分別在什么情況下更合適使用渊鞋?

1).GCD是底層的C語言構(gòu)成的API绰更,而NSOperationQueue是基于GCD的OC封裝。

2).GCD支持FIFO隊(duì)列锡宋,NSOperationQueue可以方便設(shè)置執(zhí)行順序儡湾,設(shè)置最大的并發(fā)數(shù)量。

3).NSOperationQueue可以方便地設(shè)置operation之間的依賴關(guān)系执俩,GCD則需要更多的代碼徐钠。

4).NSOperationQueue支持KVO,可以檢測operation是否正在執(zhí)行(isExecuted)役首,是否結(jié)束(isFinished)丹皱,是否取消(isCanceled)。

5).GCD的執(zhí)行速度比NSOperationQueue快宋税。

使用場合:

任務(wù)之間不太相互依賴:GCD摊崭;

任務(wù)之間依賴或者監(jiān)聽任務(wù)的執(zhí)行情況:NSOperationQueue


38、問:什么時(shí)候需要使用自動(dòng)釋放池杰赛?

官方解釋:基本分為如下三點(diǎn)

1呢簸、當(dāng)我們需要?jiǎng)?chuàng)建大量的臨時(shí)變量的時(shí)候,可以通過@autoreleasepool 來減少內(nèi)存峰值乏屯。

2根时、創(chuàng)建了新的線程執(zhí)行Cocoa調(diào)用。

3辰晕、如果您的應(yīng)用程序或線程是長期存在的蛤迎,并且可能會(huì)生成大量自動(dòng)釋放的對象,那么您應(yīng)該定期清空并創(chuàng)建自動(dòng)釋放池(就像UIKit在主線程上所做的那樣)含友;否則替裆,自動(dòng)釋放的對象會(huì)累積校辩,內(nèi)存占用也會(huì)增加。但是辆童,如果創(chuàng)建的線程不進(jìn)行Cocoa調(diào)用宜咒,則不需要?jiǎng)?chuàng)建自動(dòng)釋放池。

追問:為什么會(huì)減少內(nèi)存峰值把鉴?

答:借用YYImage的代碼打個(gè)比方故黑。

比如業(yè)務(wù)需要在一個(gè)代碼塊中需要?jiǎng)?chuàng)建大量臨時(shí)變量,或臨時(shí)變量足夠大庭砍,占用了很多內(nèi)存场晶,可以在臨時(shí)變量使用完以后就立即釋放掉,在ARC的環(huán)境下只能通過自動(dòng)釋放池實(shí)現(xiàn)怠缸。

if ([UIDevice currentDevice].isSimulator) {

? ? ? ? @autoreleasepool {

? ? ? ? ? ? NSString *outPath = [NSString stringWithFormat:@"%@ermilio.gif.png",IMAGE_OUTPUT_DIR];

? ? ? ? ? ? NSData *outData = UIImagePNGRepresentation([UIImage imageWithData:gif]);

? ? ? ? ? ? [outData writeToFile:outPath atomically:YES];

? ? ? ? ? ? [gif writeToFile:[NSString stringWithFormat:@"%@ermilio.gif",IMAGE_OUTPUT_DIR] atomically:YES];

? ? ? ? }

? ? ? ? @autoreleasepool {

? ? ? ? ? ? NSString *outPath = [NSString stringWithFormat:@"%@ermilio.apng.png",IMAGE_OUTPUT_DIR];

? ? ? ? ? ? NSData *outData = UIImagePNGRepresentation([UIImage imageWithData:apng]);

? ? ? ? ? ? [outData writeToFile:outPath atomically:YES];

? ? ? ? ? ? [apng writeToFile:[NSString stringWithFormat:@"%@ermilio.png",IMAGE_OUTPUT_DIR] atomically:YES];

? ? ? ? }

? ? ? ? @autoreleasepool {

? ? ? ? ? ? NSString *outPath = [NSString stringWithFormat:@"%@ermilio_q85.webp.png",IMAGE_OUTPUT_DIR];

? ? ? ? ? ? NSData *outData = UIImagePNGRepresentation([YYImageDecoder decodeImage:webp_q85 scale:1]);

? ? ? ? ? ? [outData writeToFile:outPath atomically:YES];

? ? ? ? ? ? [webp_q85 writeToFile:[NSString stringWithFormat:@"%@ermilio_q85.webp",IMAGE_OUTPUT_DIR] atomically:YES];

? ? ? ? }

}

再比如在循環(huán)的場景下诗轻,如果創(chuàng)建大量的臨時(shí)變量,會(huì)使內(nèi)存峰值持續(xù)增加凯旭,加入自動(dòng)釋放池以后止喷,在每次循環(huán)結(jié)束時(shí)矮烹,超出自動(dòng)釋放池的作用域,使得內(nèi)部的大量臨時(shí)變量被釋放继控,從而大大降低了內(nèi)存的使用侦高。

for (int i = 0; i < count; i++) {

? ? ? ? @autoreleasepool {

? ? ? ? ? ? id imageSrc = _images[i];

? ? ? ? ? ? NSDictionary *frameProperty = NULL;

? ? ? ? ? ? if (_type == YYImageTypeGIF && count > 1) {

? ? ? ? ? ? ? ? frameProperty = @{(NSString *)kCGImagePropertyGIFDictionary : @{(NSString *) kCGImagePropertyGIFDelayTime:_durations[i]}};

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? frameProperty = @{(id)kCGImageDestinationLossyCompressionQuality : @(_quality)};

? ? ? ? ? ? }

}

上述這幾種情況如果沒必要就別這么寫嫉柴,畢竟創(chuàng)建自動(dòng)釋放池也需要耗費(fèi)內(nèi)存。



40奉呛、iOS面試題:有了線程计螺,你覺得為什么還要有runloop?瞧壮,runloop和線程有什么關(guān)系登馒?

解析:關(guān)于為什么要,我覺得runloop是來管理(調(diào)度)線程的咆槽,當(dāng)線程的runloop被開啟后陈轿,線程會(huì)在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài),有了任務(wù)就會(huì)被喚醒去執(zhí)行任務(wù)秦忿。

關(guān)于這兩者的更多關(guān)系:

* runloop與線程是一一對應(yīng)的麦射,一個(gè)runloop對應(yīng)一個(gè)核心的線程,為什么說是核心的灯谣,是因?yàn)閞unloop是可以嵌套的潜秋,但是核心的只能有一個(gè),他們的關(guān)系保存在一個(gè)全局的字典里胎许。

* runloop在第一次獲取時(shí)被創(chuàng)建峻呛,在線程結(jié)束時(shí)被銷毀罗售。

* 對于主線程來說,runloop在程序一啟動(dòng)就默認(rèn)創(chuàng)建好了杀饵。

* 對于子線程來說莽囤,runloop是懶加載的,只有當(dāng)我們使用的時(shí)候才會(huì)創(chuàng)建切距,所以在子線程用定時(shí)器要注意:確保子線程的runloop被創(chuàng)建朽缎,不然定時(shí)器不會(huì)回調(diào)。

41谜悟、iOS面試題:NSOperation 與 GCD 的主要區(qū)別话肖?

? 1. GCD 的核心是 C 語言寫的系統(tǒng)服務(wù),執(zhí)行和操作簡單高效葡幸,因此 NSOperation 底層也通過 GCD 實(shí)現(xiàn)最筒,換個(gè)說法就是 NSOperation 是對 GCD 更高層次的抽象,這是他們之間最本質(zhì)的區(qū)別蔚叨。因此如果希望自定義任務(wù)床蜘,建議使用 NSOperation;

? 2. 依賴關(guān)系蔑水,NSOperation 可以設(shè)置兩個(gè) NSOperation 之間的依賴邢锯,第二個(gè)任務(wù)依賴于第一個(gè)任務(wù)完成執(zhí)行,GCD 無法設(shè)置依賴關(guān)系搀别,不過可以通過dispatch_barrier_async來實(shí)現(xiàn)這種效果丹擎;

? 3. KVO(鍵值對觀察),NSOperation 和容易判斷 Operation 當(dāng)前的狀態(tài)(是否執(zhí)行歇父,是否取消)蒂培,對此 GCD 無法通過 KVO 進(jìn)行判斷;

? 4. 優(yōu)先級(jí)榜苫,NSOperation 可以設(shè)置自身的優(yōu)先級(jí)护戳,但是優(yōu)先級(jí)高的不一定先執(zhí)行,GCD 只能設(shè)置隊(duì)列的優(yōu)先級(jí)垂睬,無法在執(zhí)行的 block 設(shè)置優(yōu)先級(jí)媳荒;

? 5. 繼承,NSOperation 是一個(gè)抽象類羔飞,實(shí)際開發(fā)中常用的兩個(gè)類是 NSInvocationOperation 和 NSBlockOperation 肺樟,同樣我們可以自定義 NSOperation,GCD 執(zhí)行任務(wù)可以自由組裝逻淌,沒有繼承那么高的代碼復(fù)用度么伯;

? 6. 效率,直接使用 GCD 效率確實(shí)會(huì)更高效卡儒,NSOperation 會(huì)多一點(diǎn)開銷田柔,但是通過 NSOperation 可以獲得依賴俐巴,優(yōu)先級(jí),繼承硬爆,鍵值對觀察這些優(yōu)勢欣舵,相對于多的那么一點(diǎn)開銷確實(shí)很劃算,魚和熊掌不可得兼缀磕,取舍在于開發(fā)者自己缘圈;


42、你是否接觸過OC中的反射機(jī)制袜蚕?簡單聊一下概念和使用糟把、OC

OC的反射是基于其Runtime實(shí)現(xiàn)的。

反射牲剃,一般表現(xiàn)在字符串和Class轉(zhuǎn)換遣疯,字符串和內(nèi)部方法轉(zhuǎn)換,字符串和屬性的轉(zhuǎn)換(取值和賦值)凿傅。


? class反射

? 1缠犀、通過類名的字符串形式實(shí)例化對象

Class class NSClassFromString@(@"student"); Student *stu = [[class alloc ]init];

? 2、將類名變?yōu)樽址?/p>

Class class =[Student class];

NSString *className = NSStringFromClass(class);

? SEL的反射

? 1聪舒、通過方法的字符串形式實(shí)例化方法

SEL selector = NSSelectorFromClass(@"setName"); [stu performSelector:selector withObject:@"Mike"];

2辨液、將方法變?yōu)樽址?/p>

NSStringFomrSelector(@selector*(setName:))

反射機(jī)制使用技巧 :假設(shè)有一天公司產(chǎn)品要實(shí)現(xiàn)一個(gè)需求:根據(jù)后臺(tái)推送過來的數(shù)據(jù),進(jìn)行動(dòng)態(tài)頁面跳轉(zhuǎn)过椎,跳轉(zhuǎn)到頁面后根據(jù)返回到數(shù)據(jù)執(zhí)行對應(yīng)的操作室梅。 遇到這樣奇葩的需求戏仓,我們當(dāng)然可以問產(chǎn)品都有哪些情況執(zhí)行哪些方法疚宇,然后寫一大堆if else判斷或switch判斷。 但是這種方法實(shí)現(xiàn)起來太low了赏殃,而且不夠靈活敷待,假設(shè)后續(xù)版本需求變了,還要往其他已有頁面中跳轉(zhuǎn)仁热,這不就傻眼了嗎.... 這種情況反射機(jī)制就派上用場了榜揖,我們可以用反射機(jī)制動(dòng)態(tài)的創(chuàng)建類并執(zhí)行方法。當(dāng)然也可以通過runtime來實(shí)現(xiàn)這個(gè)功能抗蠢,但是我們當(dāng)前需求反射機(jī)制已經(jīng)足夠滿足需求了举哟,如果遇到更加復(fù)雜的需求可以考慮用runtime來實(shí)現(xiàn)。 這時(shí)候就需要和后臺(tái)配合了迅矛,我們首先需要和后臺(tái)商量好返回的數(shù)據(jù)結(jié)構(gòu)妨猩,以及數(shù)據(jù)格式、類型等秽褒,返回后我們按照和后臺(tái)約定的格式壶硅,根據(jù)后臺(tái)返回的信息威兜,直接進(jìn)行反射和調(diào)用即可。


43庐椒、為什么NSAarray用copy修飾椒舵,而NSMutableArray不能用copy修飾

因?yàn)镹SMutableArray用copy修飾,所得到的實(shí)際是NSArray约谈,在刪除笔宿、添加等操作會(huì)crash。

44棱诱、如何訪問并修改一個(gè)類的私有屬性措伐?

? kvc

? 通過runtime訪問并修改私有屬性

45、在一個(gè)對象的方法里面:self.name= “object”军俊;和 name =”object” 有什么不同嗎?

答:self.name =”object”:會(huì)調(diào)用對象的setName()方法侥加;

name = “object”:會(huì)直接把object賦值給當(dāng)前對象的name屬性。

46粪躬、iOS block內(nèi)為什么要使用strongSelf

先摘抄一段來自AFNetworking的一段代碼:

__weak __typeof(self)weakSelf = self;

AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {

? ? __strong __typeof(weakSelf)strongSelf = weakSelf;

? ? strongSelf.networkReachabilityStatus = status;

? ? if (strongSelf.networkReachabilityStatusBlock) {

? ? ? ? strongSelf.networkReachabilityStatusBlock(status);

? ? }

};

我們知道使用weakSelf的作用是為了防止強(qiáng)循環(huán)引用, 產(chǎn)生不必要的內(nèi)存泄漏問題. 但是為什么在block內(nèi)部還要重新轉(zhuǎn)成strongSelf.

究其原因, 因?yàn)樵赽lock內(nèi)部的weakSelf有可能為為self或者為nil (比如當(dāng)前界面正在加載網(wǎng)絡(luò)數(shù)據(jù), 而此時(shí)用戶關(guān)閉了該界面). 這樣在某些情況下代碼會(huì)崩潰. 所以為了讓self不為nil, 我們在block內(nèi)部將weakSelf轉(zhuǎn)成strongSelf. 因?yàn)閟trongSelf在block內(nèi)部屬于局部變量了担败,當(dāng)block結(jié)束時(shí), 該strongSelf變量也會(huì)被自動(dòng)釋放., 既避免了循環(huán)引用, 又讓self在block內(nèi)部不為nil.?

故為了保證self在block執(zhí)行過程里一直存在镰官,對他強(qiáng)引用strongSelf


47提前、fmdb框架

答:數(shù)據(jù)庫框架,對sqllite的數(shù)據(jù)操作進(jìn)行了封裝泳唠,使用著可把精力都放在sql語句上面狈网。

FMDB同時(shí)兼容ARC和非ARC工程,會(huì)自動(dòng)根據(jù)工程配置來調(diào)整相關(guān)的內(nèi)存管理代碼笨腥。 FMDB常用類: FMDatabase:一個(gè)單一的SQLite數(shù)據(jù)庫拓哺,用于執(zhí)行SQL語句。 FMResultSet:執(zhí)行一個(gè)FMDatabase結(jié)果集脖母。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FMDatabaseQueue:在多個(gè)線程中執(zhí)行查詢和更新時(shí)會(huì)用到這個(gè)類士鸥。內(nèi)部是同步串行隊(duì)列來保證數(shù)據(jù)庫訪問的安全性

1,輕量級(jí)谆级,靈活烤礁。不消耗太多性能

2,F(xiàn)MDB將?語言的iOS的系統(tǒng)的SQLite的數(shù)據(jù)庫的操作代碼用OC進(jìn)行封裝肥照,面向?qū)ο蠼抛校菀桌斫夂褪褂?

注意:補(bǔ)補(bǔ)自己的sql,外鍵舆绎、索引鲤脏、多表查詢等

48、TCP和UDP的區(qū)別

答:他們類似申通和韻達(dá)快遞亿蒸,是傳輸層協(xié)議凑兰。

TCP可靠的數(shù)據(jù)流傳輸掌桩,而UDP提供的是不可靠的數(shù)據(jù)流傳輸。

簡單的說姑食,TCP注重?cái)?shù)據(jù)安全波岛,而UDP數(shù)據(jù)傳輸快點(diǎn),但安全性一般

48音半、http和scoket通信的區(qū)別则拷。

答:由于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立曹鸠,通信雙方即可開始相互發(fā)送數(shù)據(jù)內(nèi)容煌茬,直到雙方連接斷開。但在實(shí)際網(wǎng)絡(luò)應(yīng)用中彻桃,客戶端到服務(wù)器之間的通信往往需要穿越多個(gè)中間節(jié)點(diǎn)坛善,例如路由器、網(wǎng)關(guān)邻眷、防火墻等眠屎,大部分防火墻默認(rèn)會(huì)關(guān)閉長時(shí)間處于非活躍狀態(tài)的連接而導(dǎo)致 Socket 連接斷連,因此需要通過輪詢告訴網(wǎng)絡(luò)肆饶,該連接處于活躍狀態(tài)改衩。

  而HTTP連接使用的是“請求—響應(yīng)”的方式即三次握手,不僅在請求時(shí)需要先建立連接驯镊,而且需要客戶端向服務(wù)器發(fā)出請求后葫督,服務(wù)器端才能回復(fù)數(shù)據(jù)。

很多情況下板惑,需要服務(wù)器端主動(dòng)向客戶端推送數(shù)據(jù)橄镜,保持客戶端與服務(wù)器數(shù)據(jù)的實(shí)時(shí)與同步。此時(shí)若雙方建立的是Socket連接洒放,服務(wù)器就可以直接將數(shù)據(jù)傳送給客戶端蛉鹿;若雙方建立的是HTTP連接滨砍,則服務(wù)器需要等到客戶端發(fā)送一次請求后才能將數(shù)據(jù)傳回給客戶端往湿,因此,客戶端定時(shí)向服務(wù)器端發(fā)送連接請求惋戏,不僅可以保持在線领追,同時(shí)也是在“詢問”服務(wù)器是否有新的數(shù)據(jù),如果有就將數(shù)據(jù)傳給客戶端响逢。

區(qū)別簡述:

  1)http是一種協(xié)議绒窑,socket是一種編程接口,主要包括TCP協(xié)議和UDP協(xié)議;

  2)http和TCP/UDP是兩個(gè)不同層上的的協(xié)議舔亭。http是應(yīng)用層的協(xié)議些膨,TCP/UDP是傳輸層的協(xié)議蟀俊,http是在TCP/UDP之上的協(xié)議,http協(xié)議使用了TCP/UDP,http更加高級(jí)一點(diǎn)但是沒有很好的靈活性订雾。也就是http使用起來比TCP/UDP要簡單肢预,只需要遵循規(guī)范就可以進(jìn)行網(wǎng)絡(luò)通信了。

49洼哎、GCD常見的死鎖問題之一

問:打印的結(jié)果是什么烫映?結(jié)果1:因?yàn)閳?zhí)行到這個(gè)同步線程這里就死鎖了;結(jié)果2:1噩峦、3锭沟、2 ;

原因分析:因?yàn)閐ispatch_async()被放到了主隊(duì)列的末尾執(zhí)行识补,即結(jié)束了viewDidLoad 主隊(duì)列中的內(nèi)容才執(zhí)行這個(gè)族淮;首先,無論是同步sync還是異步async 都是調(diào)用一個(gè)block凭涂,這個(gè)block會(huì)被放到指定的隊(duì)列(queue)的隊(duì)尾等待執(zhí)行(重點(diǎn):隊(duì)尾等待執(zhí)行)瞧筛;至于block中是并行執(zhí)行還是串行執(zhí)行那就和dispatch_sync中的參數(shù)指定的queue是并行還是串行有關(guān);不同的是sync地等到block有結(jié)果了才能進(jìn)行下一步操作也就是nslog(@"3");而async不需要导盅,可以和nslog(@"3")同時(shí)執(zhí)行较幌;同步(sync) 操作,它會(huì)阻塞當(dāng)前線程并等待 Block 中的任務(wù)執(zhí)行完畢白翻,然后當(dāng)前線程才會(huì)繼續(xù)往下運(yùn)行乍炉;異步(async)操作,它不會(huì)阻塞當(dāng)前的線程滤馍,會(huì)一起執(zhí)行任務(wù)岛琼;viewDidLoad操作是由上到下一步一步往下執(zhí)行的,dispatch_sync提交一個(gè)打印任務(wù)NSLog(@”2”)到主線程關(guān)聯(lián)的串行隊(duì)列中巢株,主線程關(guān)聯(lián)的串行隊(duì)列現(xiàn)在有一個(gè)viewDidLoad任務(wù)槐瑞,打印任務(wù)NSLog(@”2”)排在viewDidLoad后面,隊(duì)列FIFO(先進(jìn)先出)的原則阁苞,打印任務(wù)NSLog(@”2”);想要得到執(zhí)行必須等到viewDidLoad執(zhí)行完畢后才能得到執(zhí)行困檩,但是viewDidLoad想要執(zhí)行完畢必須要等打印任務(wù)NSLog(@”2”)執(zhí)行完畢,所以就卡死在這了那槽。

50悼沿、Category(類別)、 Extension(擴(kuò)展)和繼承的區(qū)別

區(qū)別:

1. 分類有名字骚灸,類擴(kuò)展沒有分類名字糟趾,是?一種特殊的分類。

2. 分類只能擴(kuò)展?方法(屬性僅僅是聲明,并沒真正實(shí)現(xiàn))义郑,類擴(kuò)展可以擴(kuò)展屬性蝶柿、成 員變量量和?方法。

3. 繼承可以增加非驮,修改或者刪除?方法只锭,并且可以增加屬性。

51院尔、為什么代理要用weak?block和代理的區(qū)別?他們哪個(gè)性能好蜻展,為什么?

通過weak打破循環(huán)引?用邀摆。 代理和block的區(qū)別:代理和block的共同特性是回調(diào)機(jī)制纵顾。不同的是代理的方法比較多,比較注重過程栋盹。block代碼比較集中施逾、簡潔,比較注重結(jié)果;代理的運(yùn)行成本要低于block的運(yùn)行成本例获,block的出站需要從棧內(nèi)存拷?到堆內(nèi)存汉额。公共接?比較多時(shí),用代理解耦;簡單回調(diào)和異步線程中使用block榨汤。

52蠕搜、在一個(gè)UIView上放一個(gè)按鈕,如圖1收壕,請問B部分點(diǎn)擊有反應(yīng)嗎妓灌?


圖1

答:沒反應(yīng),原因就是按鈕在UIView中超出了范圍蜜宪,超出范圍的部分當(dāng)然點(diǎn)擊不到了這主要與iOS的事件分發(fā)機(jī)制(hit-Testing)有關(guān)虫埂。hit-Testing作用是找出點(diǎn)擊的是哪一個(gè)view,UIView中有兩個(gè)方法來確定hit-TestView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;//如果在當(dāng)前view中圃验,就返回該view

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;//判斷觸摸點(diǎn)是否在某個(gè)UIView中

備注:父 View 的 hitTest:withEvent 中掉伏,會(huì)調(diào)用子 View 的 pointInside:withEvent:,根據(jù)后者的結(jié)果判斷點(diǎn)擊的點(diǎn)是否在當(dāng)前的 子 view 中澳窑。

解決方案在UIView中重寫hitTest:withEvent:方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

? ? UIView *view = [super hitTest:point withEvent:event];

? ? CGPoint tempPoint = [self.btn convertPoint:point fromView:self];

? ? if ([self.btn pointInside:tempPoint withEvent:event]) {

? ? ? ? return self.btn;

? ? }

? ? return view;

}


53斧散、用weak修飾的UIView *a,addSubview添加到另一個(gè)UIView? *b上照捡,a能顯示出來嗎颅湘?

答:不能,weak 修飾的 屬性栗精,init 不會(huì) 使引用計(jì)數(shù) + 1,strong修飾的 屬性,init 會(huì)使 引用計(jì)數(shù) + 1悲立,addsubView 方法 會(huì)把 控件 添加到 subView 中鹿寨,而subView是copy修飾,引用+1薪夕。所以:weak 修飾的控件 沒有加到 VIew上 引用計(jì)數(shù) 為0脚草,就被釋放了

但是我們看到系統(tǒng)xib或者storyboard拖的屬性能顯示出來,那是因?yàn)橄到y(tǒng)內(nèi)部對它所綁定的屬性做了強(qiáng)引用操作

54原献、在block中打破循環(huán)引用有幾種方法馏慨?

1、使用weak

2姑隅、在把使用的變量,在使用完后=nil;

55写隶、鏈表與數(shù)組的區(qū)別?

(1)存儲(chǔ)形式:數(shù)組是一塊連續(xù)的空間讲仰,聲明時(shí)就要確定長度慕趴。鏈表是一塊可不連續(xù)的動(dòng)態(tài)空間,長度可變鄙陡,每個(gè)節(jié)點(diǎn)要保存相鄰結(jié)點(diǎn)指針冕房;

(2)數(shù)據(jù)查找:數(shù)組的線性查找速度快,查找操作直接使用偏移地址趁矾。鏈表需要按順序檢索結(jié)點(diǎn)耙册,效率低;

(3)數(shù)據(jù)插入或刪除:鏈表可以快速插入和刪除結(jié)點(diǎn)毫捣,而數(shù)組則可能需要大量數(shù)據(jù)移動(dòng)觅玻;

(4)越界問題:鏈表不存在越界問題,數(shù)組有越界問題培漏。

數(shù)組便于查詢溪厘,鏈表便于插入刪除。數(shù)組節(jié)省空間但是長度固定牌柄,鏈表雖然變長但是占了更多的存儲(chǔ)空間畸悬。

鏈接:https://blog.csdn.net/dangzhangjing97/article/details/81699050

56、NSArray是放在堆還是棧里的珊佣?

1蹋宦、這個(gè)的分情況,


57咒锻、? __weak與__block修飾符有什么區(qū)別冷冗?

__block:特點(diǎn) 1.__block對象在block中是可以被修改、重新賦值的惑艇。 2.__block對象在block中不會(huì)被block強(qiáng)引用一次蒿辙,從而不會(huì)出現(xiàn)循環(huán)引用問題拇泛。3.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象思灌,還可以修飾基本數(shù)據(jù)類型俺叭。

__weak:特點(diǎn) 1.__weak只能在ARC模式下使用,也只能修飾對象(NSString)泰偿,不能修飾基本數(shù)據(jù)類型(int)熄守。2、weak 關(guān)鍵字的作用弱引用耗跛,所引用對象的計(jì)數(shù)器不會(huì)加一裕照,并在引用對象被釋放的時(shí)候自動(dòng)被設(shè)置為 nil。所以可以避免循環(huán)引用调塌。

區(qū)別:

1.__weak只能在ARC模式下使用晋南,也只能修飾對象(NSString),不能修飾基本數(shù)據(jù)類型(int)

2.__block不管是ARC還是MRC模式下都可以使用烟阐,可以修飾對象搬俊,還可以修飾基本數(shù)據(jù)類型。

3.__block對象可以在block中被重新賦值蜒茄,__weak不可以唉擂。

4.__block對象在ARC下可能會(huì)導(dǎo)致循環(huán)引用,非ARC下會(huì)避免循環(huán)引用檀葛,__weak只在ARC下使用玩祟,

58刻坊、ios的內(nèi)存分區(qū)情況碰逸,這個(gè)得了解要不然問你底層就很懵逼

內(nèi)存分區(qū):棧區(qū)黎比,堆區(qū)箫踩,文字常量區(qū),全局區(qū)呛梆,代碼區(qū)

1衩椒、棧區(qū)(stack):

-棧區(qū)(stack)由編譯器自動(dòng)分配釋放 ,存放方法(函數(shù))的參數(shù)值, 局部變量的值等尤误,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)楚殿,是一塊連續(xù)的內(nèi)存的區(qū)域撮慨。即棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的(2M)

- 它是后入先出(LIFO)機(jī)制:比如瓶子里面裝東西 最上面是最后放的,最先拿出來

-棧區(qū)(stack)由編譯器自動(dòng)分配釋放 ,存放方法(函數(shù))的參數(shù)值, 局部變量的值等

- 程序猿不需要管理?xiàng)^(qū)變量的內(nèi)存脆粥;

2砌溺、堆區(qū)(heap):

-堆區(qū)(heap)一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)由OS回收,向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)变隔,是不連續(xù)的內(nèi)存區(qū)域规伐,從而堆獲得的空間比較靈活

-ios初始化方法以 new, alloc, retain,copy 開頭都是在堆區(qū)匣缘;

-- 它是先入先出(FIFO)機(jī)制:比如隧道猖闪,先進(jìn)先出

-需要程序猿管理內(nèi)存鲜棠;

-ARC的內(nèi)存的管理,是編譯器再編譯的時(shí)候自動(dòng)添加 retain萧朝、release岔留、autorelease夏哭;

3检柬、全局區(qū)/靜態(tài)區(qū)(static):

包括兩個(gè)部分:未初始化過 、初始化過竖配;也就是說何址,(全局區(qū)/靜態(tài)區(qū))在內(nèi)存中是放在一起的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域进胯, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域用爪;

4、常量區(qū):常量字符串就是放在這里的胁镐。 程序結(jié)束后由系統(tǒng)釋放 偎血;

5、代碼區(qū): 存放App代碼盯漂;

堆棧區(qū)別:1.管理方式不同 2.空間大小不同 3.能否產(chǎn)生碎片 4.生長方向不同 5.分配方式不同 6.分配效率不同颇玷;

詳細(xì)解釋:

1.管理方式:對于棧來講,是由編譯器自動(dòng)管理就缆,無需我們手工控制帖渠;對于堆來說,釋放工作由程序員控制竭宰,容易產(chǎn)生memory leak

2.空間大锌战肌:一般來講在32位系統(tǒng)下,堆內(nèi)存可以達(dá)到4G的空間切揭,從這個(gè)角度來看堆內(nèi)存幾乎是沒有什么限制的狞甚。但是對于棧來講,一般都是有一定的空間大小的廓旬,例如哼审,在VC6下面,默認(rèn)的椸脱瑁空間大小是2M棺蛛。當(dāng)然,我們可以修改: 打開工程巩步,依次操作菜單如下:Project->Setting->Link旁赊,在Category 中選中Output,然后在Reserve中設(shè)定堆棧的最大值和commit椅野。 注意:reserve最小值為4Byte终畅;commit是保留在虛擬內(nèi)存的頁文件里面籍胯,它設(shè)置的較大會(huì)使棧開辟較大的值,可能增加內(nèi)存的開銷和啟動(dòng)時(shí)間离福。

3.碎片問題:對于堆來講杖狼,頻繁的new/delete勢必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片妖爷,使程序效率降低蝶涩。對于棧來講,則不會(huì)存在這個(gè)問題絮识,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列绿聘,他們是如此的一一對應(yīng),以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出.

4.生長方向:對于堆來講次舌,生長方向是向上的熄攘,也就是向著內(nèi)存地址增加的方向;對于棧來講彼念,它的生長方向是向下的挪圾,是向著內(nèi)存地址減小的方向增長。

5.分配方式:堆都是動(dòng)態(tà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)行釋放忆嗜,無需我們手工實(shí)現(xiàn)。

6.分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu)崎岂,計(jì)算機(jī)會(huì)在底層對棧提供支持:分配專門的寄存器存放棧的地址捆毫,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高冲甘。堆則是C/C++函數(shù)庫提供的绩卤,它的機(jī)制是很復(fù)雜的。例如為了分配一塊內(nèi)存江醇,庫函數(shù)會(huì)按照一定的算法(具體的算法可以參考數(shù)據(jù)結(jié)構(gòu)/操作系統(tǒng))在堆內(nèi)存中搜索可用的足夠大小的空間濒憋,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多),就有可能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間陶夜,這樣就有機(jī)會(huì)分到足夠大小的內(nèi)存凛驮,然后進(jìn)行返回。顯然条辟,堆的效率比棧要低得多黔夭。

59宏胯、KVC的底層實(shí)現(xiàn)?

當(dāng)一個(gè)對象調(diào)用setValue方法時(shí),方法內(nèi)部會(huì)做一下操作:

1本姥、檢查存在相應(yīng)key的set方法肩袍,如果存在,就調(diào)用set方法

2婚惫、如果set方法不存在氛赐,就會(huì)查找與key相同名稱并且?guī)聞澗€成員屬性,如果有辰妙,則直接給成員屬性賦值

3鹰祸、如果沒有找到_key,就會(huì)啊查找相同名稱的屬性key,如果有就直接賦值

4甫窟、如果還是沒找到密浑,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法

這些方法的默認(rèn)實(shí)現(xiàn)都是拋出異常,我們可以根據(jù)要重寫它們

60粗井、KVO的底層實(shí)現(xiàn)尔破?

- kvo基于runtime機(jī)制實(shí)現(xiàn)

-使用了isa混寫(isa-swizzling),當(dāng)一個(gè)對象(假設(shè)是Person對象)的屬性值(Person的屬性age)發(fā)生改變時(shí),系統(tǒng)會(huì)自動(dòng)生成一個(gè)類浇衬,繼承Person懒构,NSKVONotifying_Person,在這個(gè)類的setAge方法里面,調(diào)用[super setAge:age]耘擂、[self willChangeValueForKey:@"age"]和[self didChangeValueForKey:@"age"],而這2個(gè)方法內(nèi)部會(huì)主動(dòng)調(diào)用監(jiān)聽者內(nèi)部的-(void)observeValueForKeyPath這個(gè)方法胆剧。

-當(dāng)你觀察一個(gè)對象時(shí),一個(gè)新的類會(huì)動(dòng)態(tài)被創(chuàng)建醉冤。這個(gè)類繼承自該對象的原本的類秩霍,并重寫了被觀察屬性的 setter方法。自然蚁阳,重寫的 setter方法會(huì)負(fù)責(zé)在調(diào)用原 setter方法之前和之后铃绒,通知所有觀察對象值的更改。最后把這個(gè)對象的 isa指針 ( isa 指針告訴 Runtime 系統(tǒng)這個(gè)對象的類是什么 ) 指向這個(gè)新創(chuàng)建的子類螺捐,對象就神奇的變成了新創(chuàng)建的子類的實(shí)例颠悬。

-想要看到NSKVONotifying_Person很簡單,在self.person.age=20;這個(gè)打斷點(diǎn)定血,在調(diào)試區(qū)域就能看到_person->NSObject->isa=(Class)NSKVONotifying_Person

61赔癌、ios推送原理

APNS:服務(wù)器推送給蘋果服務(wù)器,蘋果服務(wù)器推送給蘋果設(shè)備澜沟,蘋果設(shè)置推送給app

蘋果通過uuid和推送證書生成deviceToken,這個(gè)deviceToken是唯一的灾票,作用 確定是哪個(gè)手機(jī)哪個(gè)app,

62、進(jìn)程是什么倔喂?線程是什么铝条?二者有什么區(qū)別和聯(lián)系靖苇?

答:一個(gè)程序至少一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程班缰;

進(jìn)程:一個(gè)程序的一次運(yùn)行贤壁,在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享一塊內(nèi)存

線程:線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元

聯(lián)系:線程是進(jìn)程的基本組成單元

區(qū)別:

(1)調(diào)度:線程作為調(diào)度和分配的基本單位埠忘,進(jìn)程作為擁有資源的基本單位

(2)并發(fā)性:不僅進(jìn)程之間可以并發(fā)執(zhí)行脾拆,同一個(gè)進(jìn)程的多個(gè)線程之間也可并發(fā)執(zhí)行

(3)擁有資源:進(jìn)程是擁有資源的一個(gè)獨(dú)立單元,線程不擁有系統(tǒng)資源莹妒,但可以訪問隸屬于進(jìn)程的資源

(4)系統(tǒng)開銷:在創(chuàng)建或撤銷進(jìn)程時(shí)名船,由于系統(tǒng)都要為之分配和回收資源,導(dǎo)致系統(tǒng)開銷明顯大于創(chuàng)建或撤銷線程的開銷旨怠。比如操作系統(tǒng)有多個(gè)軟件在運(yùn)行(QQ渠驼、office、音樂等)鉴腻,這些都是一個(gè)個(gè)進(jìn)程迷扇,而每個(gè)進(jìn)程里又有好多線程(比如QQ、你可以同時(shí)聊天爽哎,發(fā)送文件等)

63蜓席、如何追蹤app崩潰率,如何解決線上閃退课锌?

當(dāng)iOS設(shè)備上的App應(yīng)用閃退時(shí)厨内,操作系統(tǒng)會(huì)生成一個(gè)crash日志,保存在設(shè)備上渺贤。crash日志上有很多有用的信息雏胃,比如每個(gè)正在執(zhí)行線程的完整堆棧跟蹤信息和內(nèi)存映像,這樣就能夠通過解析這些信息進(jìn)而定位crash發(fā)生時(shí)的代碼邏輯癣亚,從而找到App閃退的原因丑掺。通常來說,crash產(chǎn)生來源于兩種問題:違反iOS系統(tǒng)規(guī)則導(dǎo)致的crash和App代碼邏輯BUG導(dǎo)致的crash述雾,下面分別對他們進(jìn)行分析街州。

違反iOS系統(tǒng)規(guī)則產(chǎn)生crash的三種類型:

(1) 內(nèi)存報(bào)警閃退

當(dāng)iOS檢測到內(nèi)存過低時(shí),它的VM系統(tǒng)會(huì)發(fā)出低內(nèi)存警告通知玻孟,嘗試回收一些內(nèi)存唆缴;如果情況沒有得到足夠的改善,iOS會(huì)終止后臺(tái)應(yīng)用以回收更多內(nèi)存黍翎;最后面徽,如果內(nèi)存還是不足,那么正在運(yùn)行的應(yīng)用可能會(huì)被終止掉。在Debug模式下趟紊,可以主動(dòng)將客戶端執(zhí)行的動(dòng)作邏輯寫入一個(gè)log文件中氮双,這樣程序童鞋可以將內(nèi)存預(yù)警的邏輯寫入該log文件,當(dāng)發(fā)生如下截圖中的內(nèi)存報(bào)警時(shí)霎匈,就是提醒當(dāng)前客戶端性能內(nèi)存吃緊戴差,可以通過Instruments工具中的Allocations 和 Leaks模塊庫來發(fā)現(xiàn)內(nèi)存分配問題和內(nèi)存泄漏問題。

(2) 響應(yīng)超時(shí)

當(dāng)應(yīng)用程序?qū)σ恍┨囟ǖ氖录ū热鐔?dòng)铛嘱、掛起暖释、恢復(fù)、結(jié)束)響應(yīng)不及時(shí)墨吓,蘋果的Watchdog機(jī)制會(huì)把應(yīng)用程序干掉球匕,并生成一份相應(yīng)的crash日志。這些事件與下列UIApplicationDelegate方法相對應(yīng)帖烘,當(dāng)遇到Watchdog日志時(shí)亮曹,可以檢查上圖中的幾個(gè)方法是否有比較重的阻塞UI的動(dòng)作。

(3) 用戶強(qiáng)制退出

一看到“用戶強(qiáng)制退出”蚓让,首先可能想到的雙擊Home鍵乾忱,然后關(guān)閉應(yīng)用程序。不過這種場景一般是不會(huì)產(chǎn)生crash日志的历极,因?yàn)殡p擊Home鍵后,所有的應(yīng)用程序都處于后臺(tái)狀態(tài)衷佃,而iOS隨時(shí)都有可能關(guān)閉后臺(tái)進(jìn)程趟卸,當(dāng)應(yīng)用阻塞界面并停止響應(yīng)時(shí)這種場景才會(huì)產(chǎn)生crash日志。這里指的“用戶強(qiáng)制退出”場景氏义,是稍微比較復(fù)雜點(diǎn)的操作:先按住電源鍵锄列,直到出現(xiàn)“滑動(dòng)關(guān)機(jī)”的界面時(shí),再按住Home鍵惯悠,這時(shí)候當(dāng)前應(yīng)用程序會(huì)被終止掉邻邮,并且產(chǎn)生一份相應(yīng)事件的crash日志。

常見的崩潰原因基本都是代碼邏輯問題或資源問題克婶,比如數(shù)組越界筒严,訪問野指針或者資源不存在,或資源大小寫錯(cuò)誤等情萤。

線上Bug:項(xiàng)目使用了騰訊bugly鸭蛙,因此會(huì)有崩潰日志,通過解析dYSM可以直接定位到大部分bug崩潰之處筋岛。解決線上bug需要從主干拉一個(gè)新的分支娶视,解決bug并測試通過后,再合并到主干,然后上線肪获。若是多團(tuán)隊(duì)開發(fā)寝凌,可以將fix bug分支與其他團(tuán)隊(duì)最近要上線的分支集成,然后集成測試再上線孝赫。

測試Bug:根據(jù)測試所反饋的bug描述硫兰,若語義不清晰,則直接找到提bug人寒锚,操作給開發(fā)人員看劫映,最好是可以bug復(fù)現(xiàn)。解決bug時(shí)刹前,若能根據(jù)描述直接定位bug出錯(cuò)之處泳赋,則好處理;若無法直觀定位喇喉,則根據(jù)bug類型分幾種處理方式祖今,比如崩潰的bug可以通過instruments來檢測、數(shù)據(jù)顯示錯(cuò)誤的bug拣技,則需要閱讀代碼一步步查看邏輯哪里寫錯(cuò)

64千诬、隊(duì)列和棧有什么區(qū)別?

答:隊(duì)列和棧是兩種不同的數(shù)據(jù)容器膏斤,從“數(shù)據(jù)結(jié)構(gòu)”的角度看徐绑,它們都是線性結(jié)構(gòu),即數(shù)據(jù)元素之間的關(guān)系相同莫辨。

隊(duì)列是一種先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu)傲茄,它在兩端進(jìn)行操作,一端進(jìn)入隊(duì)列操作沮榜,一端進(jìn)行出隊(duì)列操作

棧是一種先進(jìn)后出(LIFO)的數(shù)據(jù)結(jié)構(gòu),它只能在棧頂進(jìn)行操作盘榨,入棧和出棧都在棧頂操作

65、什么是死鎖蟆融?死鎖的4個(gè)必要條件草巡?如何避免死鎖?

答:線程死鎖是指由于兩個(gè)或者多個(gè)線程互相持有對方所需要的資源型酥,導(dǎo)致這些線程處于等待狀態(tài)山憨,無法前往執(zhí)行。比如你需要你兄弟的一樣?xùn)|西去完成一個(gè)任務(wù) 冕末,他不能給萍歉。同時(shí)你兄弟需要你的一樣?xùn)|西去完成一個(gè)任務(wù),你不能給档桃。因此你們兩誰也無法完成任務(wù)枪孩。

1、 互斥條件:進(jìn)程對于所分配到的資源具有排它性,即資源不能被共享蔑舞,只能由一個(gè)進(jìn)程使用(一個(gè)資源只能被一個(gè)進(jìn)程占用拒担,直到被該方法進(jìn)程釋放 。)

2攻询、請求和保持條件:一個(gè)進(jìn)程因請求被占用資源而發(fā)生阻塞時(shí)从撼,對已獲得的資源保持不放。

3钧栖、 非剝奪條件:任何一個(gè)資源在沒被該進(jìn)程釋放之前低零,任何其進(jìn)程都無法對他剝奪占用。

4拯杠、循環(huán)等待條件:當(dāng)發(fā)生死鎖時(shí)掏婶,所等待的進(jìn)程必定會(huì)形成一個(gè)環(huán)路(類似于死循環(huán)),造成永久阻塞潭陪。

以上這四個(gè)條件是死鎖的必要條件雄妥,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立依溯,而只要上述條件之一不滿足老厌,就不會(huì)發(fā)生死鎖。線程死鎖和進(jìn)程死鎖都一樣

打破互斥條件:改造獨(dú)占性資源為虛擬資源黎炉,大部分資源已無法改造枝秤。

打破不可搶占條件:當(dāng)一進(jìn)程占有一獨(dú)占性資源后又申請一獨(dú)占性資源而無法滿足,則退出原占有的資源拜隧。

打破占有且申請條件:采用資源預(yù)先分配策略宿百,即進(jìn)程運(yùn)行前申請全部資源,滿足則運(yùn)行洪添,不然就等待,這樣就不會(huì)占有且申請雀费。

打破循環(huán)等待條件:實(shí)現(xiàn)資源有序分配策略干奢,對所有設(shè)備實(shí)現(xiàn)分類編號(hào),所有進(jìn)程只能采用按序號(hào)遞增的形式申請資源盏袄。

死鎖的處理:鴕鳥策略忿峻、預(yù)防策略、避免策略辕羽、檢測與解除死鎖

66逛尚、以下代碼死鎖了怎么解決?

-(void)methodA{? [_loack lock];? [self methodB];? [_lock unlock];}

-(void)methodB{? [_lock lock];? //操作邏輯;? [_lock unlock];}

NSLock是非遞歸鎖刁愿,當(dāng)同一線程重復(fù)獲取同一非遞歸鎖時(shí)绰寞,就會(huì)發(fā)生死鎖

解決辦法:我們可以用NSRecursiveLock或者@synchronized替代NSLock因?yàn)镹SRecursiveLock或者@synchronized都是遞歸鎖,遞歸鎖:它允許同一線程多次加鎖,而不會(huì)造成死鎖滤钱。

67觉壶、int 和NSIntger有什么區(qū)別?

NSInteger會(huì)根據(jù)系統(tǒng)的位數(shù)(32or64)自動(dòng)選擇int的最大數(shù)值(int or long)

68件缸、怎么防止反編譯铜靶?

1、本地?cái)?shù)據(jù)加密:NSUserDefaults,sqlite儲(chǔ)存文件數(shù)據(jù)加密他炊,保護(hù)賬號(hào)和關(guān)鍵字信息

2争剿、URL編碼加密:對程序中出現(xiàn)的URL進(jìn)行編碼加密,防止URL被靜態(tài)分析

3痊末、網(wǎng)絡(luò)傳輸數(shù)據(jù)加密:對客戶端傳輸數(shù)據(jù)提供加密方案蚕苇,有效防止通過網(wǎng)絡(luò)接口的攔截獲取數(shù)據(jù)

4、方法體舌胶,方法名高級(jí)混淆:對應(yīng)用程序的方法名和方法體進(jìn)行混淆捆蜀,保證源碼被逆向后無法解析代碼

5、程序結(jié)構(gòu)混排加密:對應(yīng)用程序邏輯結(jié)構(gòu)進(jìn)行打亂混排幔嫂,保證源碼可讀性降到最低

69辆它、做過的項(xiàng)目是否涉及網(wǎng)絡(luò)訪問功能,使用什么對象完成網(wǎng)絡(luò)功能履恩?

ASIHTTPRequest 與NSURLConnection

對應(yīng)第三方框架 ASI? AFN

70锰茉、MRC和ARC有什么區(qū)別?


71切心、工廠模式是什么飒筑?什么是抽象工廠?

工廠模式:專門定義一個(gè)類來負(fù)責(zé)創(chuàng)建其他類的實(shí)例绽昏,被創(chuàng)建的實(shí)例通常具有共同的父類协屡。

抽象工廠:抽象工廠提供一個(gè)固定的接口,用于創(chuàng)建一系列有關(guān)聯(lián)或相依存的對象全谤,而不必指定其具體類或其創(chuàng)建的細(xì)節(jié)肤晓。客戶端與從工廠得到的具體對象之間沒有耦合

意圖:定義一個(gè)創(chuàng)建對象的接口认然,讓其子類自己決定實(shí)例化哪一個(gè)工廠類补憾,工廠模式使其創(chuàng)建過程延遲到子類進(jìn)行。比如創(chuàng)建個(gè)水果類卷员,子類可以是香蕉盈匾、橘子、蘋果

優(yōu)點(diǎn): 1毕骡、一個(gè)調(diào)用者想創(chuàng)建一個(gè)對象削饵,只要知道其名稱就可以了岩瘦。 2、擴(kuò)展性高葵孤,如果想增加一個(gè)產(chǎn)品担钮,只要擴(kuò)展一個(gè)工廠類就可以。 3尤仍、屏蔽產(chǎn)品的具體實(shí)現(xiàn)箫津,調(diào)用者只關(guān)心產(chǎn)品的接口。

缺點(diǎn):每次增加一個(gè)產(chǎn)品時(shí)宰啦,都需要增加一個(gè)具體類和對象實(shí)現(xiàn)工廠苏遥,使得系統(tǒng)中類的個(gè)數(shù)成倍增加,在一定程度上增加了系統(tǒng)的復(fù)雜度赡模,同時(shí)也增加了系統(tǒng)具體類的依賴田炭。這并不是什么好事。

鏈接:https://blog.csdn.net/shihuboke/article/details/73921535

72漓柑、看以下代碼

NSMutableString *string = [NSMutableString stringWithString: @"origin"];

//copy

NSString *stringCopy = [string copy];

NSMutableString *mStringCopy = [string copy];

NSMutableString *stringMCopy = [string mutableCopy];

//change value

[mStringCopy appendString:@"mm"]; //這行代碼會(huì)crash

[string appendString:@" origion!"];

[stringMCopy appendString:@"!!"];

運(yùn)行以上代碼教硫,會(huì)在第7行crash,原因就是 copy 返回的對象是 immutable 對象辆布,違反了我們上述中的原則瞬矩。 注釋第7行后再運(yùn)行懦鼠,查看內(nèi)存塑娇,發(fā)現(xiàn) string、stringCopy坤邪、stringMCopy 三個(gè)對象的內(nèi)存地址都不一樣惭蹂,說明此時(shí)都是做內(nèi)容拷貝伞插。


圖1

73、assign修飾對象會(huì)怎么樣盾碗?

會(huì)造成野指針媚污,導(dǎo)致崩潰。首先我們需要明確廷雅,對象的內(nèi)存一般被分配到堆上杠步,基本數(shù)據(jù)類型和oc數(shù)據(jù)類型一本被分配在棧上。

如果用assign修飾對象榜轿,當(dāng)對象釋放后(因?yàn)椴淮嬖趶?qiáng)引用,離開作用域?qū)ο髢?nèi)存可能被回收)朵锣,指針的地址還是存在的谬盐,也就是說指針并沒有被置為nil,下次再訪問該對象就會(huì)造成野指針異常。對象時(shí)分配在堆上的诚些,堆上的內(nèi)存由程序員手動(dòng)釋放飞傀。

assign修飾基本數(shù)據(jù)類型或OC數(shù)據(jù)類型皇型,因?yàn)榛緮?shù)據(jù)類型是分配在棧上的,由系統(tǒng)分配和釋放砸烦,所以不會(huì)造成野指針弃鸦。

74、OC的野指針是什么幢痘,常見的情況有哪些唬格,如何避免?

1颜说、如果一個(gè)指針先前指向一個(gè)對象购岗,但這個(gè)對象隨后被釋放了,如果該指針沒有做任何的修改门粪,導(dǎo)致仍然指向著那塊內(nèi)存地址(被釋放后的內(nèi)存)喊积,則該指針已成為了野指針。

比如:Student *stu = [[Student alloc] init];

[stu setAge:10];

[stu release];這里已經(jīng)釋放內(nèi)存

[stu setAge:10];---》報(bào)錯(cuò)

如果改動(dòng)一下代碼玄妈,就不會(huì)報(bào)錯(cuò)[stu release]; (stu = nil; 這里是重點(diǎn)) [stu setAge:10]; //消息是無法發(fā)送出去的乾吻,不會(huì)造成任何的影響,當(dāng)然也不會(huì)報(bào)錯(cuò)拟蜻。

常見的野指針:1绎签、代理用assign修飾 2、assign修飾對象 3瞭郑、創(chuàng)建的對象提前釋放了辜御,然后再去拿著這個(gè)指針操作這個(gè)對象? 4、2個(gè)指針指向同一個(gè)對象屈张,然后其中一個(gè)指針把對象釋放了擒权,另一個(gè)指針還指著這個(gè)對象,然后這個(gè)指針就是野指針了阁谆。比如:Student *stu = [[Student alloc] init];? self.xxx=stu;? [stu rease];


75碳抄、iOS 空指針 、野指針场绿、 僵尸對象是什么意思剖效?

空指針:沒有指向任何內(nèi)存地址的指針,比如被賦值為nil的指針焰盗,在沒有被具體初始化之前璧尸,為nil。

野指針:指向垃圾內(nèi)存(對象被釋放了的內(nèi)存或者或者不可用的內(nèi)存)的指針

僵尸對象:已經(jīng)被釋放的對象熬拒。如果在程序中再度使用該對象爷光,一般會(huì)出現(xiàn)如下報(bào)錯(cuò):

unrecognized selector sent to instance

76、內(nèi)存泄露怎么檢測澎粟?

內(nèi)存泄露:是指申請的內(nèi)存空間使用完畢之后未回收蛀序。

一次內(nèi)存泄露危害可以忽略欢瞪,但若一直泄漏,無論有多少內(nèi)存徐裸,遲早都會(huì)被占用光遣鼓,最終導(dǎo)致程序crash。(因此重贺,開發(fā)中我們要盡量避免內(nèi)存泄漏的出現(xiàn))

第一種:靜態(tài)分析方法(Analyze)

第二種:動(dòng)態(tài)分析方法(Instrument工具庫里的Leaks)

目前骑祟,在ARC環(huán)境下,導(dǎo)致內(nèi)存泄漏的根本原因是代碼中存在循環(huán)引用檬姥,從而導(dǎo)致一些內(nèi)存無法釋放曾我,最終導(dǎo)致dealloc()方法無法被調(diào)用。所以你只要看你的ViewController是否調(diào)用dealloc()方法健民,基本就可以斷定是否有內(nèi)存泄露了

77抒巢、Assets里的圖片與Resoure里的圖片有什么區(qū)別?

其實(shí)這個(gè)考的是他們加載的的2個(gè)方法

[UIImage imageNamed:@"xx"];? 和[UIImage imageWithContentsOfFile:path];

1秉犹、前者比后者代碼少蛉谜,因?yàn)榍罢呦到y(tǒng)會(huì)去根據(jù)不同屏幕去加載不同的尺寸的圖片@2x @3x,而后者要自己判斷

2崇堵、前者可以緩存到內(nèi)存可以多次使用型诚,后者使用過后就銷毀了不長期占用內(nèi)存,這條才是重點(diǎn)

然而他們的缺點(diǎn)也就暴露了鸳劳,所以看情況而定在項(xiàng)目中使用哪種吧

78狰贯、你們項(xiàng)目一般用什么布局?

這個(gè)時(shí)候你就要說出代碼布局和xib或者storyboard的優(yōu)缺點(diǎn)

1赏廓、代碼好處就是好維護(hù)涵紊,修改起來方便

2、xib/storyboard 寫界面快幔摸,不好就是修改約束麻煩摸柄,如果多人開發(fā)容易沖突

3、還有一點(diǎn)他們加載速度不一樣既忆,代碼快驱负,xib/storyboard慢,主要體現(xiàn)在打開xcode ,如果是運(yùn)行的話其實(shí)看不出來患雇,但是還是代碼快

總結(jié)一句話:想后期維護(hù)便捷呢跃脊,就用代碼,只想開發(fā)一個(gè)版本呢苛吱,就用xib

79匾乓、frame 和 bounds 的理解?

frame:當(dāng)前視圖在父視圖的位置和大小

bounds:當(dāng)前視圖在自身坐標(biāo)系統(tǒng)中的位置大小,默認(rèn)x,y{0,0};

區(qū)別:frame決定自己在父控件的位置和大小又谋,父控件位置要變

bounds決定子控件在自己內(nèi)部的位置和大小拼缝,父控件位置不變

比如父控件的bounds,x-20,父控件不會(huì)有變化,但是子控件會(huì)像下移動(dòng)20像素

比如:系統(tǒng)tableview的cell在屏幕上滑動(dòng)就是利用這個(gè)原理bounds的y變化影響cell的上下滑動(dòng)彰亥,而cell的frame的值沒有任何變化

80咧七、__block和__weak的作用及區(qū)別?

1任斋、__block不管是ARC還是MRC模式下都可以使用,而__weak只能在ARC模式下使用继阻。

2、__block可以修飾對象和基本數(shù)據(jù)類型废酷。 __weak只能修飾對象瘟檩。

3、__block對象可以在block中被重新賦值澈蟆,__weak不可以被重新賦值墨辛。

4、當(dāng)用__block和__weak分別修飾一個(gè)對象趴俘,__block會(huì)持有該對象睹簇,即使超出了該對象的作用域,該對象還是會(huì)存在的寥闪,直到block對象從堆上銷毀太惠;而__weak僅僅是將該對象賦值給weak對象,當(dāng)該對象銷毀時(shí)疲憋,weak對象將指向nil凿渊;

在block中防止循環(huán)引用需要注意的問題:

__block本身不能避免循環(huán)引用,如要避免要在block中把 __block修飾的對象置為nil缚柳。另外需要注意在MRC模式下__block是不會(huì)引起retain埃脏;但是在ARC模式下__block則會(huì)引起retain。所以ARC中建議使用__weak喂击。

__weak可以避免循環(huán)引用剂癌,但是會(huì)導(dǎo)致外部對象釋放后,block內(nèi)部也訪問不到該對象翰绊,可以通過在block內(nèi)部聲明一個(gè)__strong的變量佩谷,使其指向 weakObj,這樣外部對象既可以在 block 內(nèi)部保持住监嗜,又可以避免循環(huán)引用的問題谐檀。

81、NStimer準(zhǔn)嗎裁奇?談?wù)勀愕目捶ㄍ┾咳绻粶?zhǔn)該怎樣實(shí)現(xiàn)一個(gè)精確的NSTimer?

1.不準(zhǔn)

2.不準(zhǔn)的原因如下:

1、NSTimer加在main runloop中刽肠,模式是NSDefaultRunLoopMode溃肪,main負(fù)責(zé)所有主線程事件免胃,例如UI界面的操作,復(fù)雜的運(yùn)算惫撰,這樣在同一個(gè)runloop中timer就會(huì)產(chǎn)生阻塞羔沙。

2、模式的改變厨钻。主線程的 RunLoop 里有兩個(gè)預(yù)置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode扼雏。

當(dāng)你創(chuàng)建一個(gè)Timer 并加到 DefaultMode 時(shí),Timer 會(huì)得到重復(fù)回調(diào)夯膀,但此時(shí)滑動(dòng)一個(gè)ScrollView時(shí)诗充,RunLoop 會(huì)將mode 切換為 TrackingRunLoopMode,這時(shí) Timer

就不會(huì)被回調(diào)诱建,并且也不會(huì)影響到滑動(dòng)操作蝴蜓。所以就會(huì)影響到NSTimer不準(zhǔn)的情況。

PS:DefaultMode 是 App 平時(shí)所處的狀態(tài)涂佃,rackingRunLoopMode 是追蹤 ScrollView 滑動(dòng)時(shí)的狀態(tài)励翼。

方法一:

1、在主線程中進(jìn)行NSTimer操作辜荠,但是將NSTimer實(shí)例加到main runloop的特定mode(模式)中汽抚。避免被復(fù)雜運(yùn)算操作或者UI界面刷新所干擾。

self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(showTime) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

2伯病、在子線程中進(jìn)行NSTimer的操作造烁,再在主線程中修改UI界面顯示操作結(jié)果;

- (void)timerMethod2 {

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];

[thread start];}

- (void)newThread

{@autoreleasepool

{[NSTimer scheduledTimerWithTimeInterval:1.0target:self selector:@selector(showTime) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] run];}}

總結(jié):

一開始的時(shí)候系統(tǒng)就為我們將主線程的main runloop隱式的啟動(dòng)了午笛。

在創(chuàng)建線程的時(shí)候惭蟋,可以主動(dòng)獲取當(dāng)前線程的runloop。每個(gè)子線程對應(yīng)一個(gè)runloop

82药磺、編寫頁面頂部輪播圖告组,實(shí)現(xiàn)無限滾動(dòng)(實(shí)現(xiàn)邏輯即可)?

現(xiàn)在的App開發(fā)中癌佩,輪播圖幾乎是一個(gè)不可避免的都會(huì)用到的木缝。個(gè)人封裝過輪播圖,也看過很多種不同的輪播圖围辙,目前掌握的輪播圖無限輪播有四種不同的實(shí)現(xiàn)方式:

第一種:基于collectionView進(jìn)行的封裝(推薦)

這種方式應(yīng)該是實(shí)現(xiàn)起來最簡單的一種方式了我碟,也是個(gè)人最喜歡的一種封裝方式。它的原理就是幾個(gè)collectionView姚建,至于無限輪播矫俺,很簡單,只需要你的輪播數(shù)組給collectionView賦值的時(shí)候乘以一個(gè)較大的數(shù)字即可(例如100),collectionView本身處理了重用等一系列問題厘托。

更好的實(shí)現(xiàn)代碼:https://blog.csdn.net/Mo_Mo123/article/details/77824262

第二種:基于scrollView的無限輪播(首尾各多創(chuàng)建一個(gè)展示圖片的ImageView)

這種實(shí)現(xiàn)方式個(gè)人感覺是最麻煩友雳,而且還需要考慮重用等性能問題的一種〈吆妫基本的原理就是在根據(jù)你輪播數(shù)組的個(gè)數(shù)在首尾各多創(chuàng)建一個(gè)ImageView沥阱,當(dāng)然首位之前多創(chuàng)建一個(gè)展示輪播數(shù)組最后一個(gè)的ImageView,而尾部多創(chuàng)建一個(gè)展示輪播數(shù)組第一個(gè)的ImageView伊群。

例如輪播數(shù)組有4張圖。

3 0 1 2 3 0

當(dāng)用戶在滑到最左或者最右的瞬間將scrollView的偏移量進(jìn)行改變策精,因?yàn)槠涫孜哺饔幸粡埥⑹迹脩粼谝曈X上幾乎感覺不出來。

這種的缺點(diǎn)就是如果輪播數(shù)組中圖片太多咽袜,要考慮重用的問題丸卷。

第三種:同樣是基于scrollView的無限輪播(總共就創(chuàng)建三個(gè)ImageView)

這種實(shí)現(xiàn)方式比第二種的好處就是不需要考慮重用問題,不論數(shù)組是多少個(gè)輪播圖询刹,我只創(chuàng)建三個(gè)ImageView谜嫉。它與第二種的不同之處是其實(shí)用戶每次看到的一直都是中間那張的ImageView,只是上邊的內(nèi)容改變了。其內(nèi)部實(shí)現(xiàn)其實(shí)是在不斷的改變那個(gè)輪播數(shù)組凹联。

第四種:只有一個(gè)ImageView

這種實(shí)現(xiàn)方式不再基于ScrollView沐兰,同樣不存在重用等的問題。這種實(shí)現(xiàn)方式跟第三種有相似之處蔽挠,但是它跟第三種的區(qū)別是不再使用scrollView的圖片切換方式住闯。還是不停地去改變這個(gè)數(shù)組的內(nèi)容。這種實(shí)現(xiàn)方式的核心在于切換的時(shí)候使用自定義的layer層的轉(zhuǎn)場動(dòng)畫澳淑。模擬scrollView的滑動(dòng)效果比原。

82、layoutSubview什么情況下會(huì)調(diào)用杠巡?

layoutSubviews作用

layoutSubviews是對subviews重新布局量窘。比如,我們想更新子視圖的位置的時(shí)候氢拥,可以通過調(diào)用layoutSubviews方法蚌铜,即可以實(shí)現(xiàn)對子視圖重新布局。

layoutSubviews默認(rèn)是不做任何事情的兄一,用到的時(shí)候厘线,需要在子類進(jìn)行重寫。

注意:init初始化不會(huì)觸發(fā)layoutSubviews出革。

1造壮、addSubview會(huì)觸發(fā)layoutSubviews。

2、設(shè)置view的Frame會(huì)觸發(fā)layoutSubviews耳璧,當(dāng)然前提是frame的值設(shè)置前后發(fā)生了變化成箫。

3、滾動(dòng)一個(gè)UIScrollView會(huì)觸發(fā)layoutSubviews旨枯。

4蹬昌、旋轉(zhuǎn)Screen會(huì)觸發(fā)父UIView上的layoutSubviews事件。

5攀隔、改變一個(gè)UIView大小的時(shí)候也會(huì)觸發(fā)父UIView上的layoutSubviews事件皂贩。

6、直接調(diào)用setLayoutSubviews昆汹。

7明刷、直接調(diào)用setNeedsLayout。

83.__weak 和 _Unsafe_Unretain 的區(qū)別满粗?

weak 修飾的指針變量辈末,在指向的內(nèi)存地址銷毀后,會(huì)在 Runtime 的機(jī)制下映皆,自動(dòng)置為 nil挤聘。

_Unsafe_Unretain不會(huì)置為 nil,容易出現(xiàn) 懸垂指針捅彻,發(fā)生崩潰组去。但是 _Unsafe_Unretain 比 __weak 效率高。




84沟饥、atomic是百分之百線程安全的嗎添怔?



atomic不是百分之百線程安全的,只是保證多線程的情況下贤旷,getter广料、setter方法調(diào)用的完整性,在多線程訪問的情況下幼驶,能夠有效完整的調(diào)用完setter艾杏、getter方法。


但是在多線程并發(fā)的情況下盅藻,得到的結(jié)果不能夠保證是統(tǒng)一的购桑,比如說線程A在調(diào)用屬性M的setter方法并且進(jìn)行到了一半的時(shí)候,線程B調(diào)用了getter方法想要獲取到M的內(nèi)容氏淑,那么線程B拿到的是線程A賦值之前的內(nèi)容勃蜘,如果需求是要獲取到線程A賦完值以后的內(nèi)容,那么這就是線程不安全的實(shí)例假残。




83缭贡、ARC中的屬性標(biāo)示符


@property(assign/retain/strong/weak/unsafe_unretained/copy)NSObject *object;

assign 表示setter僅僅是一個(gè)簡單的賦值操作炉擅,通常用于基本的數(shù)值類型,例如CGFloat和NSInteger等阳惹,修飾oc對象容易發(fā)生野指針


strong 屬性定義了強(qiáng)引用關(guān)系谍失,當(dāng)這個(gè)屬性設(shè)置一個(gè)新值的時(shí)候:首先對新值retain,對舊值release莹汤,然后再賦值快鱼。


weak 屬性定義了弱引用關(guān)系,當(dāng)給屬性設(shè)置一個(gè)新值的時(shí)候纲岭,只是跟assign一樣簡單的賦值抹竹,如果當(dāng)屬性指向的對象銷毀的時(shí)候,該屬性會(huì)被置nil


unsafe_unretained 也是定義了一個(gè)弱引用關(guān)系止潮,與weak類似柒莉,不同點(diǎn)是unsafe_unretained修飾的屬性,指向的對象如果釋放沽翔,本屬性不會(huì)置nil


copy 類似于strong,不過在賦值時(shí)進(jìn)行copy操作而不是retain操作窿凤,通常用于保留某個(gè)不可變的對象仅偎,防止它的意外改變時(shí)使用

1 loadView方法作用

創(chuàng)建控制器的view

第一次使用控制器View的時(shí)候調(diào)用,在控制器View的get方法中調(diào)用(使用的是懶加載)

當(dāng)外界第一個(gè)使用當(dāng)前控制器的View時(shí)雳殊,會(huì)調(diào)用當(dāng)前一個(gè)方法loadView橘沥,創(chuàng)建控制器的View, 控制器的View是懶加載的夯秃,什么時(shí)候使用座咆,什么時(shí)候才去創(chuàng)建,如果已經(jīng)創(chuàng)建仓洼,就不會(huì)再創(chuàng)建了介陶。

默認(rèn)控制器View背景顏色是[UIColor clearColor]

2 loadView內(nèi)部實(shí)現(xiàn)

首先會(huì)判斷當(dāng)前控制器是否從StoryBoard中加載,如果是色建,直接加載哺呜,如果不是,再判斷有沒有Xib來描述控制器的View箕戳,如果有某残,從Xib中加載,如果沒有陵吸,loadView會(huì)直接通過[[UIView alloc] init]來創(chuàng)建玻墅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市壮虫,隨后出現(xiàn)的幾起案子澳厢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赏酥,死亡現(xiàn)場離奇詭異喳整,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)裸扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門框都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呵晨,你說我怎么就攤上這事魏保。” “怎么了摸屠?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵谓罗,是天一觀的道長。 經(jīng)常有香客問我季二,道長檩咱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任胯舷,我火速辦了婚禮刻蚯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桑嘶。我一直安慰自己炊汹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布逃顶。 她就那樣靜靜地躺著讨便,像睡著了一般。 火紅的嫁衣襯著肌膚如雪以政。 梳的紋絲不亂的頭發(fā)上霸褒,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音妙蔗,去河邊找鬼傲霸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眉反,可吹牛的內(nèi)容都是我干的昙啄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼寸五,長吁一口氣:“原來是場噩夢啊……” “哼梳凛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梳杏,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對情侶失蹤韧拒,失蹤者是張志新(化名)和其女友劉穎淹接,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叛溢,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡塑悼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了楷掉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厢蒜。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖烹植,靈堂內(nèi)的尸體忽然破棺而出斑鸦,到底是詐尸還是另有隱情,我是刑警寧澤草雕,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布巷屿,位于F島的核電站,受9級(jí)特大地震影響墩虹,放射性物質(zhì)發(fā)生泄漏嘱巾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一诫钓、第九天 我趴在偏房一處隱蔽的房頂上張望浓冒。 院中可真熱鬧,春花似錦尖坤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至墅冷,卻和暖如春纯路,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寞忿。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工驰唬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腔彰。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓叫编,卻偏偏與公主長得像,于是被迫代替她去往敵國和親霹抛。 傳聞我的和親對象是個(gè)殘疾皇子搓逾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,089評(píng)論 1 32
  • 1.設(shè)計(jì)模式是什么霞篡? 你知道哪些設(shè)計(jì)模式世蔗,并簡要敘述?設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)朗兵,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,138評(píng)論 0 12
  • 1.設(shè)計(jì)模式是什么污淋? 你知道哪些設(shè)計(jì)模式,并簡要敘述余掖? 設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)寸爆,就是用比較成熟的邏輯去處理某一種類...
    司馬DE晴空閱讀 1,278評(píng)論 0 7
  • 把網(wǎng)上的一些結(jié)合自己面試時(shí)遇到的面試題總結(jié)了一下,以后有新的還會(huì)再加進(jìn)來浊吏。 1. OC 的理解與特性 OC 作為一...
    AlaricMurray閱讀 2,546評(píng)論 0 20
  • 會(huì)會(huì)念 周一的校會(huì)我們早就做好了充分的準(zhǔn)備:往嘴巴里塞各種能充饑的而昨,餅餅、面包找田,各種能抵餓的水果……總之歌憨,就怕那肚...
    陌上花gyx閱讀 80評(píng)論 0 0