目錄
- OC的理解與特性
- OC內(nèi)存管理機(jī)制
- MVC與MVVM設(shè)計(jì)模型對比
- 垃圾回收機(jī)制
- 協(xié)議,分類,KVC,KVO,代理,通知,Block相關(guān)試題
- static,self,super,#include,#import,@class,@public、@protected、@private等關(guān)鍵詞
- CoreData相關(guān)
- 自動釋放池
- 堆和棧的區(qū)別
1 OC的理解與特性
OC作為一門面向?qū)ο蟮恼Z言,自然具有面向?qū)ο蟮恼Z言特性:封裝、繼承、多態(tài)。它既具有靜態(tài)語言的特性(如C++),又有動態(tài)語言的效率(動態(tài)綁定、動態(tài)加載等)。總體來講,OC確實(shí)是一門不錯的編程語言,
Objective-C具有相當(dāng)多的動態(tài)特性,表現(xiàn)為三方面:動態(tài)類型(Dynamic typing)、動態(tài)綁定(Dynamic binding)和動態(tài)加載(Dynamic loading)。動態(tài)——必須到運(yùn)行時(shí)(run time)才會做的一些事情。
動態(tài)類型:即運(yùn)行時(shí)再決定對象的類型,這種動態(tài)特性在日常的應(yīng)用中非常常見,簡單來說就是id類型。事實(shí)上,由于靜態(tài)類型的固定性和可預(yù)知性,從而使用的更加廣泛。靜態(tài)類型是強(qiáng)類型,而動態(tài)類型屬于弱類型,運(yùn)行時(shí)決定接受者。
動態(tài)綁定:基于動態(tài)類型,在某個實(shí)例對象被確定后,其類型便被確定了,該對象對應(yīng)的屬性和響應(yīng)消息也被完全確定。
動態(tài)加載:根據(jù)需求加載所需要的資源,最基本就是不同機(jī)型的適配,例如,在Retina設(shè)備上加載@2x的圖片,而在老一些的普通蘋設(shè)備上加載原圖,讓程序在運(yùn)行時(shí)添加代碼模塊以及其他資源,用戶可根據(jù)需要加載一些可執(zhí)行代碼和資源,而不是在啟動時(shí)就加載所有組件,可執(zhí)行代碼可以含有和程序運(yùn)行時(shí)整合的新類。
2 簡述內(nèi)存管理基本原則
之前:OC內(nèi)存管理遵循“誰創(chuàng)建,誰釋放,誰引用,誰管理”的機(jī)制,當(dāng)創(chuàng)建或引用一個對象的時(shí)候,需要向她發(fā)送alloc、copy、retain消息,當(dāng)釋放該對象時(shí)需要發(fā)送release消息,當(dāng)對象引用計(jì)數(shù)為0時(shí),系統(tǒng)將釋放該對象,這是OC的手動管理機(jī)制(MRC)。
目前:iOS 5.0之后引用自動管理機(jī)制——自動引用計(jì)數(shù)(ARC),管理機(jī)制與手動機(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)的對象就會自動釋放,而weak修飾的指針變量指向?qū)ο?,?dāng)對象的擁有者指向新值或者不存在時(shí)weak修飾的指針會自動置為nil。
如果使用alloc、copy(mutableCopy)或者retian一個對象時(shí),你就有義務(wù),向它發(fā)送一條release或者autorelease消息。其他方法創(chuàng)建的對象,不需要由你來管理內(nèi)存。
向一個對象發(fā)送一條autorelease消息,這個對象并不會立即銷毀, 而是將這個對象放入了自動釋放池,待池子釋放時(shí),它會向池中每一個對象發(fā)送 一條release消息,以此來釋放對象.
向一個對象發(fā)送release消息,并不意味著這個對象被銷毀了,而是當(dāng)這個對象的引用計(jì)數(shù)為0時(shí),系統(tǒng)才會調(diào)用dealloc方法,釋放該對象和對象本身它所擁有的實(shí)例。
其他注意事項(xiàng)
- 如果一個對象有一個
_strong類型的指針指向著,找個對象就不會被釋放。如果一個指針指向超出了它的作用域,就會被指向nil。如果一個指針被指向nil,那么它原來指向的對象就被釋放了。當(dāng)一個視圖控制器被釋放時(shí),它內(nèi)部的全局指針會被指向nil。用法“:不管全局變量還是局部變量用_strong描述就行。 - 局部變量:出了作用域,指針會被置為nil。
- 方法內(nèi)部創(chuàng)建對象,外部使用需要添加_autorelease;
- 連線的時(shí)候,用_weak描述。
- 代理使用
unsafe_unretained就相當(dāng)于assign; - block中為了避免循環(huán)引用問題,使用
_weak描述; - 聲明屬性時(shí),不要以
new開頭。如果非要以new開頭命名屬性的名字,需要自己定制get方法名,如
@property(getter=theString) NSString * newString;
- 如果要使用自動釋放池,用
@autoreleasepool{} - ARC只能管理
Foundation框架的變量,如果程序中把Foundation中的變量強(qiáng)制換成COreFoundation中的變量需要交換管理權(quán); - 在非ARC工程中采用ARC去編譯某些類:
-fobjc-arc。 - 在ARC下的工程采用非ARC去編譯某些類:
-fno-fobjc-arc。
3 如何理解MVC設(shè)計(jì)模式
MVC是一種架構(gòu)模式,M表示MOdel,V表示視圖View,C表示控制器Controller:
Model負(fù)責(zé)存儲、定義、操作數(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)行通信,這個時(shí)候就要用Notification和KVO,這個方式就像一個廣播一樣,MOdel發(fā)信號,Controller設(shè)置監(jiān)聽接受信號,當(dāng)有數(shù)據(jù)更新時(shí)就發(fā)信號給Controller,Model和View不能直接進(jìn)行通信,這樣會違背MVC設(shè)計(jì)模式。
4 如何理解MVVM設(shè)計(jì)模式
-
ViewModel層就是View和Model層的粘合劑,他是一個放置用戶輸入驗(yàn)證邏輯,視圖顯示邏輯,發(fā)起網(wǎng)絡(luò)請求和其他各種各樣的代碼的極好的地方。說白了,就是把原來ViewController層的業(yè)務(wù)邏輯和頁面邏輯等剝離出來放到ViewModel層。 -
View層就是ViewController層,他的任務(wù)就是從ViewModel層獲取數(shù)據(jù),然后顯示。
5 Objective-C 中是否支持垃圾回收機(jī)制?
OC是支持垃圾回收機(jī)制的
(Garbage collection簡稱GC),但是apple的移動終端中,是不支持GC的,Mac桌面系統(tǒng)開發(fā)中是支持的.移動終端開發(fā)是支持
ARC(Automatic Reference Counting的簡稱),ARC是在IOS5之后推出的新技術(shù),它與GC的機(jī)制是不同的。我們在編寫代碼時(shí), 不需要向?qū)ο蟀l(fā)送release或者autorelease方法,也不可以調(diào)用delloc方法,編譯器會在合適的位置自動給用戶生成release消息(autorelease),ARC 的特點(diǎn)是自動引用技術(shù)簡化了內(nèi)存管理的難度.
6 協(xié)議的基本概念和協(xié)議中方法默認(rèn)為什么類型。
OC中的協(xié)議是一個方法列表,且多少有點(diǎn)相關(guān)。它的特點(diǎn)是可以被任何類使用(實(shí)現(xiàn)),但它
并不是類(這里我們需要注意),自身不會實(shí)現(xiàn)這樣方法, 而是又其他人來實(shí)現(xiàn)協(xié)議經(jīng)常用來實(shí)現(xiàn)委托對象(委托設(shè)計(jì)模式)。如果一個類采用了一個協(xié)議,那么它必須實(shí)現(xiàn)協(xié)議中必須需要實(shí)現(xiàn)的方法,在協(xié)議中的方法
默認(rèn)是必須實(shí)現(xiàn)(@required),添加關(guān)鍵字@optional,表明一旦采用該協(xié)議,這些“可選”的方法是可以選擇不實(shí)現(xiàn)的。一個協(xié)議可以擴(kuò)展自另一個協(xié)議,如果需要擴(kuò)展多個協(xié)議中間使用逗號分隔;
和其他高級語言中接口不同的是協(xié)議中定義的方法不一定是必須實(shí)現(xiàn)的,我們可以通過關(guān)鍵字進(jìn)行@required和@optional進(jìn)行設(shè)置,如果不設(shè)置則
默認(rèn)是@required(注意ObjC是弱語法,即使不實(shí)現(xiàn)必選方法編譯運(yùn)行也不會報(bào)錯);協(xié)議通過<>進(jìn)行實(shí)現(xiàn),一個類可以同時(shí)實(shí)現(xiàn)多個協(xié)議,中間通過逗號分隔;
協(xié)議的實(shí)現(xiàn)只能在類的聲明上,不能放到類的實(shí)現(xiàn)上(也就是說必須寫成@interface Person:NSObject<AnimalDelegate>而不能寫成@implementation Person<AnimalDelegate>);
協(xié)議中不能定義屬性、成員變量等,只能定義方法;
7 簡述類目category優(yōu)點(diǎn)和缺點(diǎn)。
-
優(yōu)點(diǎn):
- 不需要通過增加子類而增加現(xiàn)有類的行為(方法),且類目中的方法與原始類方法基本沒有區(qū)別;
- 通過類目可以將龐大一個類的方法進(jìn)行劃分,從而便于代碼的日后的維護(hù)、更新以及提高代碼的閱讀性;
-
缺點(diǎn):
- 無法向類目添加實(shí)例變量,如果需要添加實(shí)例變量,只能通過定義子類的方式;
- 類目中的方法與原始類以及父類方法相比具有更高優(yōu)先級,如果覆蓋父類的方法,可能導(dǎo)致super消息的斷裂。因此,最好不要覆蓋原始類中的方法。
8 類別的作用
給系統(tǒng)原有類添加方法,不能擴(kuò)展屬性。如果類別中方法的名字跟系統(tǒng)的方法名一樣,在調(diào)用的時(shí)候類別中的方法優(yōu)先級更高;
分散類的實(shí)現(xiàn):如:
+ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section
原本屬于NSIndexPath的方法,但因?yàn)檫@個方法經(jīng)常使用的表的時(shí)候調(diào)用、跟表的關(guān)系特別密切,因此把這個方法一類別的形式、聲明在UITableView.h中。
聲明私有方法,某一個方法只實(shí)現(xiàn),不聲明,相當(dāng)于私有方法。
類別不能聲明變量,類別不可以直接添加屬性。property描述setter方法,就不會報(bào)錯。
9 循環(huán)引用的產(chǎn)生原因,以及解決方法。
產(chǎn)生原因:如下圖所示,對象A和對象B相互引用了對方作為自己的成員變量,只有自己銷毀的時(shí)候才能將成員變量的引用計(jì)數(shù)減1。對象A的銷毀依賴于對象B的銷毀,同時(shí)對象B銷毀也依賴與對象A的銷毀,從而形成循環(huán)引用,此時(shí),即使外界沒有任何指針訪問它,它也無法釋放。

解決方法:
- 事先知道存在循環(huán)引用的地方,在合理的位置主動斷開一個引用,是對象回收;
- 使用弱引用
10 鍵路徑(keyPath)、鍵值編碼(KVC)和鍵值觀察(KVO)
鍵路徑
- 在一個給定的實(shí)體中,同一個屬性的所有值具有相同的數(shù)據(jù)類型。
- 鍵-值編碼技術(shù)用于進(jìn)行這樣的查找—它是一種間接訪問對象屬性的機(jī)制。 - 鍵路徑是一個由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個連接在一起的對象性質(zhì)序列。第一個鍵的性質(zhì)是由先前的性質(zhì)決定的,接下來每個鍵的值也是相對于其前面的性質(zhì)。
- 鍵路徑使您可以以獨(dú)立于模型實(shí)現(xiàn)的方式指定相關(guān)對象的性質(zhì)。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相關(guān)對象的特定屬性。
鍵值編碼KVC
- 鍵值編碼是一種間接訪問對象的屬性使用字符串來標(biāo)識屬性,而不是通過調(diào)用存取方法,直接或通過實(shí)例變量訪問的機(jī)制,非對象類型的變量將被自動封裝或者解封成對象,很多情況下會簡化程序代碼;
- KVC的缺點(diǎn):一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設(shè)置的鍵、鍵路徑進(jìn)行錯誤檢查,且執(zhí)行效率要低于合成存取器方法和自定的 setter 和 getter 方法。因?yàn)槭褂?KVC 鍵值編碼,它必須先解析字符串,然后在設(shè)置或者訪問對象的實(shí)例變量。
鍵值觀察KVO
- 鍵值觀察機(jī)制是一種能使得對象獲取到其他對象屬性變化的通知 ,極大的簡化了代碼。
- 實(shí)現(xiàn) KVO 鍵值觀察模式,被觀察的對象必須使用 KVC 鍵值編碼來修 改它的實(shí)例變量,這樣才能被觀察者觀察到。因此,KVC是KVO的基礎(chǔ)。
KVC機(jī)制通過key找到value的原理
- 當(dāng)通過KVC調(diào)用對象時(shí),比如:[self valueForKey:@”someKey”]時(shí),程序會自動試圖通過下面幾種不同的方式解析這個調(diào)用。
- 首先查找對象是否帶有
someKey這個方法,如果沒找到,會繼續(xù)查找對象是否帶有someKey這個實(shí)例變量(iVar),如果還沒有找到,程序會繼續(xù)試圖調(diào)用-(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實(shí)現(xiàn)的話,程序會拋出一個NSUndefinedKeyException異常錯誤。 - 補(bǔ)充:KVC查找方法的時(shí)候,不僅僅會查找someKey這個方法,還會查找
getsomeKey這個方法,前面加一個get,或者_someKey以_getsomeKey這幾種形式。同時(shí),查找實(shí)例變量的時(shí)候也會不僅僅查找someKey這個變量,也會查找_someKey這個變量是否存在。 - 設(shè)計(jì)valueForUndefinedKey:方法的主要目的是當(dāng)你使用-(id)valueForKey方法從對象中請求值時(shí),對象能夠在錯誤發(fā)生前,有最后的機(jī)會響應(yīng)這個請求。
11 在 Objective-C 中如何實(shí)現(xiàn) KVO
- 注冊觀察者(注意:觀察者和被觀察者不會被保留也不會被釋放)
- (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;
- 移除對象的觀察者身份
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
KVO中誰要監(jiān)聽誰注冊,然后對響應(yīng)進(jìn)行處理,使得觀察者與被觀察者完全解耦。KVO只檢測類中的屬性,并且屬性名都是通過NSString來查找,編譯器不會檢錯和補(bǔ)全,全部取決于自己。
12 代理的作用
- 代理又叫
委托,是一種設(shè)計(jì)模式,代理是對象與對象之間的通信交互,代理解除了對象之間的耦合性。 - 改變或傳遞控制鏈。允許一個類在某些特定時(shí)刻通知到其他類,而不需要獲取到那些類的指針??梢詼p少框架復(fù)雜度。
- 另外一點(diǎn),代理可以理解為java中的回調(diào)監(jiān)聽機(jī)制的一種類似。
- 代理的屬性常是assign的原因:防止循環(huán)引用,以至對象無法得到正確的釋放。
13 NSNotification、Block、Delegate和KVO的區(qū)別。
- 代理是一種回調(diào)機(jī)制,且是一對一的關(guān)系,通知是一對多的關(guān)系,一個對向所有的觀察者提供變更通知;
- 效率:Delegate比NSNOtification高;
- Delegate和Block一般是一對一的通信;
- Delegate需要定義協(xié)議方法,代理對象實(shí)現(xiàn)協(xié)議方法,并且需要建立代理關(guān)系才可以實(shí)現(xiàn)通信;
- Block:Block更加簡潔,不需要定義繁瑣的協(xié)議方法,但通信事件比較多的話,建議使用Delegate;
14 Objective-C中可修改和不可以修改類型
- 可修改不可修改的集合類,就是可動態(tài)添加修改和不可動態(tài)添加修改。
- 比如NSArray和NSMutableArray,前者在初始化后的內(nèi)存控件就是固定不可變的,后者可以添加等,可以動態(tài)申請新的內(nèi)存空間
15 當(dāng)我們調(diào)用一個靜態(tài)方法時(shí),需要對對象進(jìn)行 release 嗎?
不需要,靜態(tài)方法(類方法)創(chuàng)建一個對象時(shí),對象已被放入自動釋放池。在自動釋放池被釋放時(shí),很有可能被銷毀。
16 當(dāng)我們釋放我們的對象時(shí),為什么需要調(diào)用[super dealloc]方法,它的位置又是如何的呢?
因?yàn)樽宇惖哪承?shí)例是繼承自父類的,因此需要調(diào)用[super dealloc]方法, 來釋放父類擁有的實(shí)例,其實(shí)也就是子類本身的。一般來說我們優(yōu)先釋放子類擁 有的實(shí)例,最后釋放父類所擁有的實(shí)例。
17 對謂詞的認(rèn)識
Cocoa 中提供了一個NSPredicate的類,該類主要用于指定過濾器的條件, 每一個對象通過謂詞進(jìn)行篩選,判斷條件是否匹配。如果需要了解使用方法,請看謂詞的具體使用
18 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)用,這個函數(shù)的使用范圍被限制在聲明.
- 在類中的static成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝.
- self:當(dāng)前消息的接收者。
- super:向父類發(fā)送消息。
19 #include與#import的區(qū)別,#import 與@class 的區(qū)別
- #include 和#import其效果相同,都是查詢類中定義的行為(方法);
- #import不會引起交叉編譯,確保頭文件只會被導(dǎo)入一次;
- @class 的表明,只定 義了類的名稱,而具體類的行為是未知的,一般用于.h 文件;
- @class 比#import 編譯效率更高。
- 此外@class 和#import 的主要區(qū)別在于解決引用死鎖的問題。
20 @public、@protected、@private 它們的含義與作用
- @public:對象的實(shí)例變量的作用域在任意地方都可以被訪問 ;
- @protected:對象的實(shí)例變量作用域在本類和子類都可以被訪問 ;
- @private:實(shí)例變量的作用域只能在本類(自身)中訪問 .
21 解釋 id 類型
任意類型對象,程序運(yùn)行時(shí)才決定對象的類型。
22 switch 語句 if 語句區(qū)別與聯(lián)系
- 均表示條件的判斷,switch語句表達(dá)式只能處理的是整型、字符型和枚舉類型,而選擇流程語句則沒有這樣的限制。
- 但switch語句比選擇流程控制語句效率更高。
23 isMemberOfClass 和 isKindOfClass 聯(lián)系與區(qū)別
- 聯(lián)系:兩者都能檢測一個對象是否是某個類的成員
- 區(qū)別:isKindOfClass 不僅用來確定一個對象是否是一個類的成員,也可以用來確定一個對象是否派生自該類的類的成員 ,而isMemberOfClass 只能做到第一點(diǎn)。
- 舉例:如 ClassA派 生 自NSObject 類 , ClassA *a = [ClassA alloc] init];,[a isKindOfClass:[NSObject class]] 可以檢查出 a 是否是 NSObject派生類 的成員,但 isMemberOfClass 做不到。
24 iOS 開發(fā)中數(shù)據(jù)持久性有哪幾種?
數(shù)據(jù)存儲的核心都是寫文件。
- 屬性列表:只有NSString、NSArray、NSDictionary、NSData可writeToFile;存儲依舊是plist文件。plist文件可以存儲的7中數(shù)據(jù)類型:array、dictionary、string、bool、data、date、number。
- 對象序列化(對象歸檔):對象序列化通過序列化的形式,鍵值關(guān)系存儲到本地,轉(zhuǎn)化成二進(jìn)制流。通過runtime實(shí)現(xiàn)自動化歸檔/解檔,請參考這個文章。實(shí)現(xiàn)NSCoding協(xié)議必須實(shí)現(xiàn)的兩個方法:
- 編碼(對象序列化):把不能直接存儲到plist文件中得到數(shù)據(jù),轉(zhuǎn)化為二進(jìn)制數(shù)據(jù),NSData,可以存儲到本地;
- 解碼(對象反序列化):把二進(jìn)制數(shù)據(jù)轉(zhuǎn)化為本來的類型
- SQLite 數(shù)據(jù)庫:大量有規(guī)律的數(shù)據(jù)使用數(shù)據(jù)庫。
- CoreData :通過管理對象進(jìn)行增、刪、查、改操作的。它不是一個數(shù)據(jù)庫,不僅可以使用SQLite數(shù)據(jù)庫來保持?jǐn)?shù)據(jù),也可以使用其他的方式來存儲數(shù)據(jù)。如:XML。
25 CoreData
CoreData的介紹:
- CoreData是面向?qū)ο蟮腁PI,CoreData是iOS中非常重要的一項(xiàng)技術(shù),幾乎在所有編寫的程序中,CoreData都作為數(shù)據(jù)存儲的基礎(chǔ)。
- CoreData是蘋果官方提供的一套框架,用來解決與對象聲明周期管理、對象關(guān)系管理和持久化等方面相關(guān)的問題。
- 大多數(shù)情況下,我們引用CoreData作為持久化數(shù)據(jù)的解決方案,并利用它作為持久化數(shù)據(jù)映射為內(nèi)存對象。提供的是對象-關(guān)系映射功能,也就是說,CoreData可以將Objective-C對象轉(zhuǎn)換成數(shù)據(jù),保存到SQL中,然后將保存后的數(shù)據(jù)還原成OC對象。
CoreData的特征:
- 通過CoreData管理應(yīng)用程序的數(shù)據(jù)模型,可以極大程度減少需要編寫的代碼數(shù)量。
- 將對象數(shù)據(jù)存儲在SQLite數(shù)據(jù)庫已獲得性能優(yōu)化。
- 提供NSFetchResultsController類用于管理表視圖的數(shù)據(jù),即將Core Data的持久化存儲在表視圖中,并對這些數(shù)據(jù)進(jìn)行管理:增刪查改。
- 管理undo/redo操縱;
- 檢查托管對象的屬性值是否正確。
Core Data的6成員對象
-
NSManageObject:被管理的數(shù)據(jù)記錄Managed Object Model是描述應(yīng)用程序的數(shù)據(jù)模型,這個模型包含實(shí)體(Entity)、特性(Property)、讀取請求(Fetch Request)等。 -
NSManageObjectContext:管理對象上下文,持久性存儲模型對象,參與數(shù)據(jù)對象進(jìn)行各種操作的全過程,并監(jiān)測數(shù)據(jù)對象的變化,以提供對undo/redo的支持及更新綁定到數(shù)據(jù)的UI。 -
NSPersistentStoreCoordinator:連接數(shù)據(jù)庫的Persistent Store Coordinator相當(dāng)于數(shù)據(jù)文件管理器,處理底層的對數(shù)據(jù)文件的讀取和寫入,一般我們與這個沒有交集。 -
NSManagedObjectModel:被管理的數(shù)據(jù)模型、數(shù)據(jù)結(jié)構(gòu)。 -
NSFetchRequest:數(shù)據(jù)請求; -
NSEntityDescription:表格實(shí)體結(jié)構(gòu),還需知道.xcdatamodel文件編譯后為.momd或者.mom文件。
Core Data的功能
- 對于KVC和KVO完整且自動化的支持,除了為屬性整合KVO和KVC訪問方法外,還整合了適當(dāng)?shù)募显L問方法來處理多值關(guān)系;
- 自動驗(yàn)證屬性(property)值;
- 支持跟蹤修改和撤銷操作;
- 關(guān)系維護(hù),Core Data管理數(shù)據(jù)的關(guān)系傳播,包括維護(hù)對象間的一致性;
- 在內(nèi)存上和界面上分組、過濾、組織數(shù)據(jù);
- 自動支持對象存儲在外部數(shù)據(jù)倉庫的功能;
- 創(chuàng)建復(fù)雜請求:無需動手寫SQL語句,在獲取請求(fetch request)中關(guān)聯(lián)NSPredicate。NSPreadicate支持基本功能、相關(guān)子查詢和其他高級的SQL特性。它支持正確的Unicode編碼、區(qū)域感知查詢、排序和正則表達(dá)式;
- 延遲操作:Core Data使用懶加載(lazy loading)方式減少內(nèi)存負(fù)載,還支持部分實(shí)體化延遲加載和復(fù)制對象的數(shù)據(jù)共享機(jī)制;
- 合并策略:Core Data內(nèi)置版本跟蹤和樂觀鎖(optimistic locking)來支持多用戶寫入沖突的解決,其中,樂觀鎖就是對數(shù)據(jù)沖突進(jìn)行檢測,若沖突就返回沖突的信息;
- 數(shù)據(jù)遷移:Core Data的Schema Migration工具可以簡化應(yīng)對數(shù)據(jù)庫結(jié)構(gòu)變化的任務(wù),在某些情況允許你執(zhí)行高效率的數(shù)據(jù)庫原地遷移工作;
- 可選擇針對程序Controller層的集成,來支持UI的顯示同步Core Data在IPhone OS之上,提供NSFetchedResultsController對象來做相關(guān)工作,在Mac OS X上我們用Cocoa提供的綁定(Binding)機(jī)制來完成的。
26 對象可以被copy的條件
- 只有實(shí)現(xiàn)了NSCopying和NSMutableCopying協(xié)議的類的對象才能被拷貝,分為不可變拷貝和可變拷貝
- NSCopying協(xié)議方法為:
- (id)copyWithZone:(NSZone *)zone;
27 自動釋放池工作原理
- 自動釋放池是NSAutorelease類的一個實(shí)例,當(dāng)向一個對象發(fā)送autorelease消息時(shí),該對象會自動入池,待池銷毀時(shí),將會向池中所有對象發(fā)送一條release消息,釋放對象。
- [pool release]、 [pool drain]表示的是池本身不會銷毀,而是池子中的臨時(shí)對象都被發(fā)送release,從而將對象銷毀。
28 在某個方法中 self.name = _name,name = _name 它 們有區(qū)別嗎,為什么?
- 前者是存在內(nèi)存管理的setter方法賦值,它會對_name對象進(jìn)行保留或者拷貝操作
- 后者是普通賦值
- 一般來說,在對象的方法里成員變量和方法都是可以訪問的,我們通常會重寫Setter方法來執(zhí)行某些額外的工作。比如說,外部傳一個模型過來,那么我會直接重寫Setter方法,當(dāng)模型傳過來時(shí),也就是意味著數(shù)據(jù)發(fā)生了變化,那么視圖也需要更新顯示,則在賦值新模型的同時(shí)也去刷新UI。
29 解釋self = [super init]方法
容錯處理,當(dāng)父類初始化失敗,會返回一個nil,表示初始化失敗。由于繼承的關(guān)系,子類是需要擁有父類的實(shí)例和行為,因此,我們必須先初始化父類,然后再初始化子類
30 定義屬性時(shí),什么時(shí)候用 assign、retain、copy 以及它們的之間的區(qū)別。
-
assign:普通賦值,一般常用于基本數(shù)據(jù)類型,常見委托設(shè)計(jì)模式, 以此來防止循環(huán)引用。(我們稱之為弱引用). -
retain:保留計(jì)數(shù),獲得到了對象的所有權(quán),引用計(jì)數(shù)在原有基礎(chǔ)上加1. -
copy:一般認(rèn)為,是在內(nèi)存中重新開辟了一個新的內(nèi)存空間,用來 存儲新的對象,和原來的對象是兩個不同的地址,引用計(jì)數(shù)分別為1。但是當(dāng)copy對象為不可變對象時(shí),那么copy 的作用相當(dāng)于retain。因?yàn)?這樣可以節(jié)約內(nèi)存空間
31 堆和棧的區(qū)別
-
棧區(qū)(stack)由編譯器自動分配釋放 ,存放方法(函數(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ū)域,從而堆獲得的空間比較靈活。 -
碎片問題:對于堆來講,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對應(yīng),以至于永遠(yuǎn)都不可能有一個內(nèi)存塊從棧中間彈出. -
分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進(jìn)行釋放,無需我們手工實(shí)現(xiàn)。 -
分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的。 -
全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲是放在一塊 的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后有系統(tǒng)釋放。 -
文字常量區(qū)—常量字符串就是放在這里的。程序結(jié)束后由系統(tǒng)釋放。 -
程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼
更多同類型文章請參考
iOS面試進(jìn)階篇(一)
iOS面試進(jìn)階篇(二)
iOS面試進(jìn)階篇(三)
iOS面試進(jìn)階篇(四)
iOS面試進(jìn)階篇(五)
書寫整理多不容易,覺得寫的好的打賞一下吧。
更多相關(guān)類型文章敬請期待中