序言
目前形勢(shì)舰蟆,參加到iOS隊(duì)伍的人是越來越多,甚至已經(jīng)到供過于求了腮猖。今年鉴扫,找過工作人可能會(huì)更深刻地體會(huì)到今年的就業(yè)形勢(shì)不容樂觀,加之澈缺,培訓(xùn)機(jī)構(gòu)一火車地向用人單位輸送iOS開發(fā)人員坪创,打破了生態(tài)圈的動(dòng)態(tài)平衡。矯情一下姐赡,言歸正傳莱预,我奉獻(xiàn)一下,為iOS應(yīng)聘者梳理一下面試題项滑,希望能助一臂之力!
一. OC的理解與特性
- OC作為一門面向?qū)ο蟮恼Z言依沮,自然具有面向?qū)ο蟮恼Z言特性:封裝、繼承、多態(tài)危喉。它既具有靜態(tài)語言的特性(如C++)宋渔,又有動(dòng)態(tài)語言的效率(動(dòng)態(tài)綁定、動(dòng)態(tài)加載等)辜限∩邓總體來講,OC確實(shí)是一門不錯(cuò)的編程語言列粪,
- Objective-C具有相當(dāng)多的動(dòng)態(tài)特性,表現(xiàn)為三方面:動(dòng)態(tài)類型(Dynamic typing)谈飒、動(dòng)態(tài)綁定(Dynamic binding)和動(dòng)態(tài)加載(Dynamic loading)岂座。動(dòng)態(tài)——必須到運(yùn)行時(shí)(run time)才會(huì)做的一些事情。
- 動(dòng)態(tài)類型:即運(yùn)行時(shí)再?zèng)Q定對(duì)象的類型杭措,這種動(dòng)態(tài)特性在日常的應(yīng)用中非常常見费什,簡(jiǎn)單來說就是id類型。事實(shí)上手素,由于靜態(tài)類型的固定性和可預(yù)知性鸳址,從而使用的更加廣泛。靜態(tài)類型是強(qiáng)類型泉懦,而動(dòng)態(tài)類型屬于弱類型稿黍,運(yùn)行時(shí)決定接受者。
- 動(dòng)態(tài)綁定:基于動(dòng)態(tài)類型崩哩,在某個(gè)實(shí)例對(duì)象被確定后巡球,其類型便被確定了,該對(duì)象對(duì)應(yīng)的屬性和響應(yīng)消息也被完全確定邓嘹。
- 動(dòng)態(tài)加載:根據(jù)需求加載所需要的資源酣栈,最基本就是不同機(jī)型的適配,例如汹押,在Retina設(shè)備上加載@2x的圖片矿筝,而在老一些的普通蘋設(shè)備上加載原圖,讓程序在運(yùn)行時(shí)添加代碼模塊以及其他資源棚贾,用戶可根據(jù)需要加載一些可執(zhí)行代碼和資源窖维,而不是在啟動(dòng)時(shí)就加載所有組件,可執(zhí)行代碼可以含有和程序運(yùn)行時(shí)整合的新類鸟悴。
二: 簡(jiǎn)述內(nèi)存管理基本原則
MRC:OC內(nèi)存管理遵循“誰創(chuàng)建陈辱,誰釋放,誰引用细诸,誰管理”的機(jī)制沛贪,當(dāng)創(chuàng)建或引用一個(gè)對(duì)象的時(shí)候,需要向她發(fā)送alloc、copy利赋、retain消息水评,當(dāng)釋放該對(duì)象時(shí)需要發(fā)送release消息,當(dāng)對(duì)象引用計(jì)數(shù)為0時(shí)媚送,系統(tǒng)將釋放該對(duì)象中燥,這是OC的手動(dòng)管理機(jī)制(MRC)。
ARC:iOS 5.0之后引用自動(dòng)管理機(jī)制——自動(dòng)引用計(jì)數(shù)(ARC)塘偎,管理機(jī)制與手動(dòng)機(jī)制一樣疗涉,只是不再需要調(diào)用retain、release吟秩、autorelease咱扣;它編譯時(shí)的特性,當(dāng)你使用ARC時(shí)涵防,在適當(dāng)位置插入release和autorelease闹伪;它引用strong和weak關(guān)鍵字,strong修飾的指針變量指向?qū)ο髸r(shí)壮池,當(dāng)指針指向新值或者指針不復(fù)存在偏瓤,相關(guān)聯(lián)的對(duì)象就會(huì)自動(dòng)釋放,而weak修飾的指針變量指向?qū)ο笠铮?dāng)對(duì)象的擁有者指向新值或者不存在時(shí)weak修飾的指針會(huì)自動(dòng)置為nil厅克。
如果使用alloc、copy(mutableCopy)或者retian一個(gè)對(duì)象時(shí),你就有義務(wù),向它發(fā)送一條release或者autorelease消息橙依。其他方法創(chuàng)建的對(duì)象,不需要由你來管理內(nèi)存已骇。
向一個(gè)對(duì)象發(fā)送一條autorelease消息,這個(gè)對(duì)象并不會(huì)立即銷毀, 而是將這個(gè)對(duì)象放入了自動(dòng)釋放池,待池子釋放時(shí),它會(huì)向池中每一個(gè)對(duì)象發(fā)送 一條release消息,以此來釋放對(duì)象.
向一個(gè)對(duì)象發(fā)送release消息,并不意味著這個(gè)對(duì)象被銷毀了,而是當(dāng)這個(gè)對(duì)象的引用計(jì)數(shù)為0時(shí),系統(tǒng)才會(huì)調(diào)用dealloc方法,釋放該對(duì)象和對(duì)象本身它所擁有的實(shí)例。
三. 內(nèi)存管理的注意事項(xiàng)
如果一個(gè)對(duì)象有一個(gè)_strong類型的指針指向著票编,找個(gè)對(duì)象就不會(huì)被釋放褪储。如果一個(gè)指針指向超出了它的作用域,就會(huì)被指向nil慧域。如果一個(gè)指針被指向nil鲤竹,那么它原來指向的對(duì)象就被釋放了。當(dāng)一個(gè)視圖控制器被釋放時(shí)昔榴,它內(nèi)部的全局指針會(huì)被指向nil辛藻。用法“:不管全局變量還是局部變量用_strong描述就行。
局部變量:出了作用域互订,指針會(huì)被置為nil吱肌。
方法內(nèi)部創(chuàng)建對(duì)象,外部使用需要添加_autorelease;
連線的時(shí)候仰禽,用_weak描述氮墨。
代理使用unsafe_unretained就相當(dāng)于assign纺蛆;
block中為了避免循環(huán)引用問題,使用_weak描述规揪;
-
聲明屬性時(shí)桥氏,不要以new開頭。如果非要以new開頭命名屬性的名字猛铅,需要自己定制get方法名字支,如
@property(getter=theString) NSString * newString;
如果要使用自動(dòng)釋放池,用@autoreleasepool{}
ARC只能管理Foundation框架的變量奸忽,如果程序中把Foundation中的變量強(qiáng)制換成Core Foundation中的變量需要交換管理權(quán)堕伪;
在非ARC工程中采用ARC去編譯某些類:-fobjc-arc。
在ARC下的工程采用非ARC去編譯某些類:-fno-fobjc-arc栗菜。
四. 如何理解MVC設(shè)計(jì)模式
- MVC是一種架構(gòu)模式刃跛,M表示Model,V表示視圖View苛萎,C表示控制器Controller:
- Model負(fù)責(zé)存儲(chǔ)、定義检号、操作數(shù)據(jù)
- View用來展示書給用戶腌歉,和用戶進(jìn)行操作交互;
- ** Controller是Model和View的協(xié)調(diào)者齐苛,Controller把Model中的數(shù)據(jù)拿過來給View用翘盖。Controller可以直接與Model和View進(jìn)行通信,而View不能和Controller直接通信凹蜂。View與Controller通信需要利用代理協(xié)議的方式馍驯,當(dāng)有數(shù)據(jù)更新時(shí),Model也要與Controller進(jìn)行通信玛痊,這個(gè)時(shí)候就要用Notification和KVO汰瘫,這個(gè)方式就像一個(gè)廣播一樣,Model發(fā)信號(hào)擂煞,Controller設(shè)置監(jiān)聽接受信號(hào)混弥,當(dāng)有數(shù)據(jù)更新時(shí)就發(fā)信號(hào)給Controller,Model和View不能直接進(jìn)行通信对省,這樣會(huì)違背MVC設(shè)計(jì)模式蝗拿。**
五. 如何理解MVVM設(shè)計(jì)模式
- ViewModel層,就是View和Model層的粘合劑蒿涎,他是一個(gè)放置用戶輸入驗(yàn)證邏輯哀托,視圖顯示邏輯,發(fā)起網(wǎng)絡(luò)請(qǐng)求和其他各種各樣的代碼的極好的地方劳秋。說白了仓手,就是把原來ViewController層的業(yè)務(wù)邏輯和頁面邏輯等剝離出來放到ViewModel層胖齐。
- View層,就是ViewController層俗或,他的任務(wù)就是從ViewModel層獲取數(shù)據(jù)市怎,然后顯示。
- 詳細(xì)可以參考MVVM隨筆
六: Objective-C中是否支持垃圾回收機(jī)制辛慰?
OC是支持垃圾回收機(jī)制的(Garbage collection簡(jiǎn)稱GC),但是apple的移動(dòng)終端中,是不支持GC的,Mac桌面系統(tǒng)開發(fā)中是支持的.
移動(dòng)終端開發(fā)是支持ARC(Automatic Reference Counting)的簡(jiǎn)稱),ARC是在IOS5之后推出的新技術(shù),它與GC的機(jī)制是不同的区匠。我們?cè)诰帉懘a時(shí), 不需要向?qū)ο蟀l(fā)送release或者autorelease方法,也不可以調(diào)用delloc方法,編譯器會(huì)在合適的位置自動(dòng)給用戶生成release消息(autorelease),ARC 的特點(diǎn)是自動(dòng)引用技術(shù)簡(jiǎn)化了內(nèi)存管理的難度.
七: 協(xié)議的基本概念和協(xié)議中方法默認(rèn)為什么類型
OC中的協(xié)議是一個(gè)方法列表,且多少有點(diǎn)相關(guān)。它的特點(diǎn)是可以被任何類使用(實(shí)現(xiàn)),但它并不是類(這里我們需要注意),自身不會(huì)實(shí)現(xiàn)這樣方法, 而是又其他人來實(shí)現(xiàn)協(xié)議經(jīng)常用來實(shí)現(xiàn)委托對(duì)象(委托設(shè)計(jì)模式)帅腌。如果一個(gè)類采用了一個(gè)協(xié)議,那么它必須實(shí)現(xiàn)協(xié)議中必須需要實(shí)現(xiàn)的方法,在協(xié)議中的方法默認(rèn)是必須實(shí)現(xiàn)(@required),添加關(guān)鍵字@optional,表明一旦采用該協(xié)議,這些“可選”的方法是可以選擇不實(shí)現(xiàn)的驰弄。
八: 簡(jiǎn)述類目category優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):
- 不需要通過增加子類而增加現(xiàn)有類的行為(方法),且類目中的方法與原始類方法基本沒有區(qū)別;
- 通過類目可以將龐大一個(gè)類的方法進(jìn)行劃分,從而便于代碼的日后的維護(hù)、更新以及提高代碼的閱讀性;
缺點(diǎn):
- 無法向類目添加實(shí)例變量,如果需要添加實(shí)例變量,只能通過定義子類的方式;
- 類目中的方法與原始類以及父類方法相比具有更高優(yōu)先級(jí),如果覆蓋父類的方法,可能導(dǎo)致super消息的斷裂速客。因此,最好不要覆蓋原始類中的方法戚篙。
九: 類別的作用
- 給系統(tǒng)原有類添加方法,不能擴(kuò)展屬性溺职。如果類別中方法的名字跟系統(tǒng)的方法名一樣岔擂,在調(diào)用的時(shí)候類別中的方法優(yōu)先級(jí)更高;
- 分散類的實(shí)現(xiàn):如:
+ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section
原本屬于NSIndexPath的方法浪耘,但因?yàn)檫@個(gè)方法經(jīng)常使用的表的時(shí)候調(diào)用乱灵、跟表的關(guān)系特別密切,因此把這個(gè)方法一類別的形式七冲、聲明在UITableView.h中痛倚。
- 聲明私有方法,某一個(gè)方法只實(shí)現(xiàn)澜躺,不聲明蝉稳,相當(dāng)于私有方法。
- 類別不能聲明變量掘鄙,類別不可以直接添加屬性耘戚。property描述setter方法,就不會(huì)報(bào)錯(cuò)操漠。
十:循環(huán)引用的產(chǎn)生原因毕莱,以及解決方法
- 產(chǎn)生原因:如下圖所示,對(duì)象A和對(duì)象B相互引用了對(duì)方作為自己的成員變量颅夺,只有自己銷毀的時(shí)候才能將成員變量的引用計(jì)數(shù)減1朋截。對(duì)象A的銷毀依賴于對(duì)象B的銷毀,同時(shí)對(duì)象B銷毀也依賴與對(duì)象A的銷毀吧黄,從而形成循環(huán)引用部服,此時(shí),即使外界沒有任何指針訪問它拗慨,它也無法釋放廓八。
多個(gè)對(duì)象間依然會(huì)存在循環(huán)引用問題奉芦,形成一個(gè)環(huán),在編程中剧蹂,形成的環(huán)越大越不容易察覺声功,如下圖所示:
解決方法:
事先知道存在循環(huán)引用的地方,在合理的位置主動(dòng)斷開一個(gè)引用宠叼,是對(duì)象回收先巴;
使用弱引用的方法。
十一: 鍵路徑(keyPath)冒冬、鍵值編碼(KVC)伸蚯、鍵值觀察(KVO)
** 鍵路徑 **
- 在一個(gè)給定的實(shí)體中,同一個(gè)屬性的所有值具有相同的數(shù)據(jù)類型。
- 鍵-值編碼技術(shù)用于進(jìn)行這樣的查找—它是一種間接訪問對(duì)象屬性的機(jī)制简烤。 - 鍵路徑是一個(gè)由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個(gè)連接在一起的對(duì)象性質(zhì)序列剂邮。第一個(gè)鍵的性質(zhì)是由先前的性質(zhì)決定的,接下來每個(gè)鍵的值也是相對(duì)于其前面的性質(zhì)。
- 鍵路徑使您可以以獨(dú)立于模型實(shí)現(xiàn)的方式指定相關(guān)對(duì)象的性質(zhì)横侦。通過鍵路徑,您可以指定對(duì)象圖中的一個(gè)任意深度的路徑,使其指向相關(guān)對(duì)象的特定屬性挥萌。
鍵值編碼KVC
- 鍵值編碼是一種間接訪問對(duì)象的屬性使用字符串來標(biāo)識(shí)屬性,而不是通過調(diào)用存取方法枉侧,直接或通過實(shí)例變量訪問的機(jī)制引瀑,非對(duì)象類型的變量將被自動(dòng)封裝或者解封成對(duì)象,很多情況下會(huì)簡(jiǎn)化程序代碼棵逊;
- KVC的缺點(diǎn):一旦使用 KVC 你的編譯器無法檢查出錯(cuò)誤,即不會(huì)對(duì)設(shè)置的鍵、鍵路徑進(jìn)行錯(cuò)誤檢查,且執(zhí)行效率要低于合成存取器方法和自定的 setter 和 getter 方法银酗。因?yàn)槭褂?KVC 鍵值編碼,它必須先解析字符串,然后在設(shè)置或者訪問對(duì)象的實(shí)例變量辆影。
鍵值觀察KVO
- 鍵值觀察機(jī)制是一種能使得對(duì)象獲取到其他對(duì)象屬性變化的通知 ,極大的簡(jiǎn)化了代碼黍特。
- 實(shí)現(xiàn) KVO 鍵值觀察模式,被觀察的對(duì)象必須使用 KVC 鍵值編碼來修 改它的實(shí)例變量,這樣才能被觀察者觀察到蛙讥。因此,KVC是KVO的基礎(chǔ)。
-
Demo
比如我自定義的一個(gè)button
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
#pragma mark KVO -
(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"highlighted"] ) {
[self setNeedsDisplay];
}
}
對(duì)于系統(tǒng)是根據(jù)keypath去取的到相應(yīng)的值發(fā)生改變灭衷,理論上來說是和kvc機(jī)制的道理是一樣的次慢。
十二: KVC機(jī)制通過key找到value的原理
- 當(dāng)通過KVC調(diào)用對(duì)象時(shí),比如:[self valueForKey:@”someKey”]時(shí)翔曲,程序會(huì)自動(dòng)試圖通過下面幾種不同的方式解析這個(gè)調(diào)用迫像。
- 首先查找對(duì)象是否帶有 someKey 這個(gè)方法,如果沒找到瞳遍,會(huì)繼續(xù)查找對(duì)象是否帶有someKey這個(gè)實(shí)例變量(iVar)闻妓,如果還沒有找到,程序會(huì)繼續(xù)試圖調(diào)用 -(id) valueForUndefinedKey:這個(gè)方法掠械。如果這個(gè)方法還是沒有被實(shí)現(xiàn)的話由缆,程序會(huì)拋出一個(gè)NSUndefinedKeyException異常錯(cuò)誤注祖。
- 補(bǔ)充:KVC查找方法的時(shí)候,不僅僅會(huì)查找someKey這個(gè)方法均唉,還會(huì)查找getsomeKey這個(gè)方法是晨,前面加一個(gè)get,或者_(dá)someKey以_getsomeKey這幾種形式舔箭。同時(shí)罩缴,查找實(shí)例變量的時(shí)候也會(huì)不僅僅查找someKey這個(gè)變量,也會(huì)查找_someKey這個(gè)變量是否存在限嫌。
- 設(shè)計(jì)valueForUndefinedKey:方法的主要目的是當(dāng)你使用-(id)valueForKey方法從對(duì)象中請(qǐng)求值時(shí)靴庆,對(duì)象能夠在錯(cuò)誤發(fā)生前,有最后的機(jī)會(huì)響應(yīng)這個(gè)請(qǐng)求怒医。
十三: **Objective-C **中如何實(shí)現(xiàn) KVO
-
注冊(cè)觀察者(注意:觀察者和被觀察者不會(huì)被保留也不會(huì)被釋放)
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
接收變更通知
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context;移除對(duì)象的觀察者身份
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;KVO中誰要監(jiān)聽誰注冊(cè)炉抒,然后對(duì)響應(yīng)進(jìn)行處理,使得觀察者與被觀察者完全解耦稚叹。KVO只檢測(cè)類中的屬性焰薄,并且屬性名都是通過NSString來查找,編譯器不會(huì)檢錯(cuò)和補(bǔ)全扒袖,全部取決于自己塞茅。
十四: 代理的作用
- 代理又叫委托,是一種設(shè)計(jì)模式季率,代理是對(duì)象與對(duì)象之間的通信交互野瘦,代理解除了對(duì)象之間的耦合性。
- 改變或傳遞控制鏈飒泻。允許一個(gè)類在某些特定時(shí)刻通知到其他類鞭光,而不需要獲取到那些類的指針∨⒁牛可以減少框架復(fù)雜度惰许。
- 另外一點(diǎn),代理可以理解為java中的回調(diào)監(jiān)聽機(jī)制的一種類似史辙。
- 代理的屬性常是assign的原因:防止循環(huán)引用,以至對(duì)象無法得到正確的釋放汹买。
十五: NSNotification、Block聊倔、Delegate和KVO的區(qū)別
- 代理是一種回調(diào)機(jī)制晦毙,且是一對(duì)一的關(guān)系,通知是一對(duì)多的關(guān)系耙蔑,一個(gè)對(duì)向所有的觀察者提供變更通知结序;
- 效率:Delegate比NSNOtification高;
- Delegate和Block一般是一對(duì)一的通信纵潦;
- Delegate需要定義協(xié)議方法徐鹤,代理對(duì)象實(shí)現(xiàn)協(xié)議方法垃环,并且需要建立代理關(guān)系才可以實(shí)現(xiàn)通信;
- Block:Block更加簡(jiǎn)潔返敬,不需要定義繁瑣的協(xié)議方法遂庄,但通信事件比較多的話,建議使用Delegate劲赠;
十六: Objective-C中可修改和不可以修改類型
- 可修改不可修改的集合類涛目,就是可動(dòng)態(tài)添加修改和不可動(dòng)態(tài)添加修改。
- 比如NSArray和NSMutableArray,前者在初始化后的內(nèi)存控件就是固定不可變的凛澎,后者可以添加等霹肝,可以動(dòng)態(tài)申請(qǐng)新的內(nèi)存空間
十七: 當(dāng)我們調(diào)用一個(gè)靜態(tài)方法時(shí),需要對(duì)對(duì)象進(jìn)行 **release **嗎?
不需要,靜態(tài)方法(類方法)創(chuàng)建一個(gè)對(duì)象時(shí),對(duì)象已被放入自動(dòng)釋放池。在自動(dòng)釋放池被釋放時(shí),很有可能被銷毀塑煎。
十八: 當(dāng)我們釋放我們的對(duì)象時(shí),為什么需要調(diào)用[super dealloc]方法,它的位置又是如何的呢?
- 因?yàn)樽宇惖哪承?shí)例是繼承自父類的,因此需要調(diào)用[super dealloc]
方法, 來釋放父類擁有的實(shí)例,其實(shí)也就是子類本身的沫换。一般來說我們優(yōu)先釋放子類擁 有的實(shí)例,最后釋放父類所擁有的實(shí)例
十九: static、self最铁、super關(guān)鍵字的作用
- 函數(shù)體內(nèi)static變量的作用范圍為該函數(shù)體讯赏,不同于auto變量,該變量的內(nèi)存只被分配一次冷尉,因此其值在下次調(diào)用時(shí)仍維持上次的值.
- 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問漱挎,但不能被模塊外其它函數(shù)訪問.
- 在模塊內(nèi)的static函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明.
- 在類中的static成員變量屬于整個(gè)類所擁有雀哨,對(duì)類的所有對(duì)象只有一份拷貝.
- self:當(dāng)前消息的接收者磕谅。
- super:向父類發(fā)送消息。
二十: #include與#import的區(qū)別 #import與@class 的區(qū)別
-
#include和#import
其效果相同,都是查詢類中定義的行為(方法); - _ #import: 不會(huì)引起交叉編譯,確保頭文件只會(huì)被導(dǎo)入一次雾棺;
- @class的表明,只定 義了類的名稱,而具體類的行為是未知的,一般用于.h 文件膊夹;
- @class比#import編譯效率更高。
- 此外@class和#import的主要區(qū)別在于解決引用死鎖的問題垢村。
二十一: @public割疾、@protected嚎卫、@private 它們的含義與作用
- @public:對(duì)象的實(shí)例變量的作用域在任意地方都可以被訪問 ;
- @protected:對(duì)象的實(shí)例變量作用域在本類和子類都可以被訪問 ;
- @private:實(shí)例變量的作用域只能在本類(自身)中訪問 .
二十二: 解釋 **id **類型
任意類型對(duì)象嘉栓,程序運(yùn)行時(shí)才決定對(duì)象的類型。
二十三: isMemberOfClass 和 isKindOfClass 聯(lián)系與區(qū)別
- 聯(lián)系:兩者都能檢測(cè)一個(gè)對(duì)象是否是某個(gè)類的成員
- 區(qū)別:isKindOfClass 不僅用來確定一個(gè)對(duì)象是否是一個(gè)類的成員,也可以用來確定一個(gè)對(duì)象是否派生自該類的類的成員 ,而isMemberOfClass 只能做到第一點(diǎn)拓诸。
- 舉例:如 ClassA派 生 自NSObject 類 , ClassA *a = [ClassA alloc] init];,[a isKindOfClass:[NSObject class]] 可以檢查出 a 是否是 NSObject派生類 的成員,但 isMemberOfClass 做不到侵佃。
二十四: iOS開發(fā)中數(shù)據(jù)持久性有哪幾種?
數(shù)據(jù)存儲(chǔ)的核心都是寫文件。
屬性列表:只有NSString奠支、NSArray馋辈、NSDictionary、NSData可writeToFile倍谜;存儲(chǔ)依舊是plist文件迈螟。plist文件可以存儲(chǔ)的7中數(shù)據(jù)類型: array叉抡、dictionary、string答毫、bool褥民、data、date洗搂、number消返。
對(duì)象序列化(對(duì)象歸檔):對(duì)象序列化通過序列化的形式,鍵值關(guān)系存儲(chǔ)到本地耘拇,轉(zhuǎn)化成二進(jìn)制流撵颊。通過runtime實(shí)現(xiàn)自動(dòng)化歸檔/解檔,請(qǐng)參考這個(gè)文章惫叛。實(shí)現(xiàn)NSCoding協(xié)議必須實(shí)現(xiàn)的兩個(gè)方法:
2.1.編碼(對(duì)象序列化):把不能直接存儲(chǔ)到plist文件中得到數(shù)據(jù)倡勇,轉(zhuǎn)化為二進(jìn)制數(shù)據(jù),NSData挣棕,可以存儲(chǔ)到本地译隘;
2.2 解碼(對(duì)象反序列化):把二進(jìn)制數(shù)據(jù)轉(zhuǎn)化為本來的類型。SQLite 數(shù)據(jù)庫:大量有規(guī)律的數(shù)據(jù)使用數(shù)據(jù)庫洛心。
CoreData :通過管理對(duì)象進(jìn)行增固耘、刪、查词身、改操作的厅目。它不是一個(gè)數(shù)據(jù)庫,不僅可以使用SQLite數(shù)據(jù)庫來保持?jǐn)?shù)據(jù)法严,也可以使用其他的方式來存儲(chǔ)數(shù)據(jù)损敷。如:XML。
二十五: CoreData的介紹:
- CoreData是面向?qū)ο蟮腁PI深啤,CoreData是iOS中非常重要的一項(xiàng)技術(shù)拗馒,幾乎在所有編寫的程序中,CoreData都作為數(shù)據(jù)存儲(chǔ)的基礎(chǔ)溯街。
- CoreData是蘋果官方提供的一套框架诱桂,用來解決與對(duì)象聲明周期管理、對(duì)象關(guān)系管理和持久化等方面相關(guān)的問題呈昔。
- 大多數(shù)情況下挥等,我們引用CoreData作為持久化數(shù)據(jù)的解決方案,并利用它作為持久化數(shù)據(jù)映射為內(nèi)存對(duì)象堤尾。提供的是對(duì)象-關(guān)系映射功能肝劲,也就是說,CoreData可以將Objective-C對(duì)象轉(zhuǎn)換成數(shù)據(jù),保存到SQL中辞槐,然后將保存后的數(shù)據(jù)還原成OC對(duì)象掷漱。
二十六: CoreData的特征:
- 通過CoreData管理應(yīng)用程序的數(shù)據(jù)模型,可以極大程度減少需要編寫的代碼數(shù)量榄檬。
- 將對(duì)象數(shù)據(jù)存儲(chǔ)在SQLite數(shù)據(jù)庫已獲得性能優(yōu)化切威。
- 提供NSFetchResultsController類用于管理表視圖的數(shù)據(jù),即將Core - Data的持久化存儲(chǔ)在表視圖中丙号,并對(duì)這些數(shù)據(jù)進(jìn)行管理:增刪查改先朦。
管理undo/redo操縱; - 檢查托管對(duì)象的屬性值是否正確犬缨。
二十七: 對(duì)象可以被copy的條件
只有實(shí)現(xiàn)了NSCopying和NSMutableCopying
協(xié)議的類的對(duì)象才能被拷貝,分為不可變拷貝和可變拷貝,具體區(qū)別戳這喳魏;
NSCopying
協(xié)議方法為:
- (id)copyWithZone:(NSZone *)zone { MyObject *copy = [[[self class] allocWithZone:
zone] init]; copy.username = [self.username copyWithZone:zone]; return copy;}
二十八: 自動(dòng)釋放池工作原理
- 自動(dòng)釋放池是NSAutorelease類的一個(gè)實(shí)例,當(dāng)向一個(gè)對(duì)象發(fā)送autorelease消息時(shí),該對(duì)象會(huì)自動(dòng)入池,待池銷毀時(shí),將會(huì)向池中所有對(duì)象發(fā)送一條release消息,釋放對(duì)象。
- [pool release]怀薛、 [pool drain]表示的是池本身不會(huì)銷毀,而是池子中的臨時(shí)對(duì)象都被發(fā)送release,從而將對(duì)象銷毀刺彩。
二十九: 定義屬性時(shí),什么時(shí)候用assign、retain枝恋、copy以及它們的之間的區(qū)別
- assign:普通賦值,一般常用于基本數(shù)據(jù)類型,常見委托設(shè)計(jì)模式, 以此來防止循環(huán)引用创倔。(我們稱之為弱引用).
- retain:保留計(jì)數(shù),獲得到了對(duì)象的所有權(quán),引用計(jì)數(shù)在原有基礎(chǔ)上加1.
- copy:一般認(rèn)為,是在內(nèi)存中重新開辟了一個(gè)新的內(nèi)存空間,用來 存儲(chǔ)新的對(duì)象,和原來的對(duì)象是兩個(gè)不同的地址,引用計(jì)數(shù)分別為1。但是當(dāng)copy對(duì)象為不可變對(duì)象時(shí),那么copy的作用相當(dāng)于retain焚碌。因?yàn)?這樣可以節(jié)約內(nèi)存空間
三十: 堆和棧的區(qū)別
- 棧區(qū)(stack)由編譯器自動(dòng)分配釋放 ,存放方法(函數(shù))的參數(shù)值, 局部變量的值等畦攘,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域十电。即棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的知押。
- 堆區(qū)(heap)一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)由OS回收,向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)鹃骂,是不連續(xù)的內(nèi)存區(qū)域台盯,從而堆獲得的空間比較靈活。
- 碎片問題:對(duì)于堆來講畏线,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù)静盅,從而造成大量的碎片,使程序效率降低寝殴。對(duì)于棧來講蒿叠,則不會(huì)存在這個(gè)問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列杯矩,他們是如此的一一對(duì)應(yīng)栈虚,以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出.
- 分配方式:堆都是動(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)孤紧。
- 分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址拒秘,壓棧出棧都有專門的指令執(zhí)行号显,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的躺酒,它的機(jī)制是很復(fù)雜的押蚤。
- 全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊 的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后有系統(tǒng)釋放羹应。
- 文字常量區(qū)—常量字符串就是放在這里的揽碘。程序結(jié)束后由系統(tǒng)釋放。
- 程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼
三十一: 對(duì)于單元格重用的理解
當(dāng)屏幕上滑出屏幕時(shí)园匹,系統(tǒng)會(huì)把這個(gè)單元格添加到重用隊(duì)列中雳刺,等待被重用,當(dāng)有新單元從屏幕外滑入屏幕內(nèi)時(shí)裸违,從重用隊(duì)列中找看有沒有可以重用的單元格掖桦,若有,就直接用供汛,沒有就重新創(chuàng)建一個(gè)滞详。
三十二: 線程與進(jìn)程的區(qū)別和聯(lián)系?
- 一個(gè)程序至少要有進(jìn)城,一個(gè)進(jìn)程至少要有一個(gè)線程.
- 進(jìn)程:資源分配的最小獨(dú)立單元,進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位.
- 線程:進(jìn)程下的一個(gè)分支,是進(jìn)程的實(shí)體,是CPU調(diào)度和分派的基本單元,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位,線程自己基本不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(程序計(jì)數(shù)器、一組寄存器紊馏、棧)料饥,但是它可與同屬一個(gè)進(jìn)程的其他線程共享進(jìn)程所擁有的全部資源。
- 進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元朱监,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性岸啡。
- 進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間赫编,一個(gè)進(jìn)程崩潰后巡蘸,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑擂送。線程有自己的堆棧和局部變量悦荒,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉嘹吨,所以多進(jìn)程的程序要比多線程的程序健壯搬味,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些碰纬。
- 但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作萍聊,只能用線程,不能用進(jìn)程悦析。
三十三: 多線程編程
- NSThread:當(dāng)需要進(jìn)行一些耗時(shí)操作時(shí)會(huì)把耗時(shí)的操作放到線程中寿桨。線程同步:多個(gè)線程同時(shí)訪問一個(gè)數(shù)據(jù)會(huì)出問題,NSlock强戴、線程同步塊亭螟、@synchronized(self){}。
- NSOperationQueue操作隊(duì)列(不需考慮線程同步問題)骑歹。編程的重點(diǎn)都放在main里面种玛,NSInvocationOperation危融、BSBlockOperation央星、自定義Operation碾盐。創(chuàng)建一個(gè)操作綁定相應(yīng)的方法,當(dāng)把操作添加到操作隊(duì)列中時(shí)衰琐,操作綁定的方法就會(huì)自動(dòng)執(zhí)行了也糊,當(dāng)把操作添加到操作隊(duì)列中時(shí),默認(rèn)會(huì)調(diào)用main方法羡宙。
- GCD(`Grand Central Dispatch)宏大的中央調(diào)度狸剃,串行隊(duì)列、并發(fā)隊(duì)列狗热、主線程隊(duì)列钞馁;
- 同步和異步:同步指第一個(gè)任務(wù)不執(zhí)行完,不會(huì)開始第二個(gè)匿刮,異步是不管第一個(gè)有沒有執(zhí)行完僧凰,都開始第二個(gè)。
- 串行和并行:串行是多個(gè)任務(wù)按一定順序執(zhí)行熟丸,并行是多個(gè)任務(wù)同時(shí)執(zhí)行训措;
- 代碼是在分線程執(zhí)行,在主線程中刷新UI光羞。