七、內(nèi)存管理
1.objc的內(nèi)存管理簡介
(1)如果您通過分配和初始化(比如[[MyClass alloc] init])的方式來創(chuàng)建對象,您就擁有這個(gè)對象,需要負(fù)責(zé)該對象的釋放吹泡。這個(gè)規(guī)則在使用NSObject的便利方法new時(shí)也同樣適用。
(2)如果您拷貝一個(gè)對象经瓷,您也擁有拷貝得到的對象爆哑,需要負(fù)責(zé)該對象的釋放。
(3)如果您保持一個(gè)對象舆吮,您就部分擁有這個(gè)對象揭朝,需要在不再使用時(shí)釋放該對象。
(4)通過alloc色冀,new, copy, retain的對象潭袱,retainCount+1;release或者autorelease后retainCount-1,如果retainCount為0時(shí),對象會(huì)被消毀锋恬,dealloc方法被調(diào)用屯换。
(5)誰擁有,誰管理与学;
2.什么是retain count?
答:引用計(jì)數(shù)(ref count或者retain count)彤悔。對象的內(nèi)部保存一個(gè)數(shù)字,表示被引用的次數(shù)癣防。
例如蜗巧,某個(gè)對象被兩個(gè)指針?biāo)赶颍ㄒ茫┠敲此膔etain count為2。需要銷毀對象的時(shí)候蕾盯,不直接調(diào)用dealloc幕屹,而是調(diào)用release蓝丙。release會(huì)讓retain count減1,只有retain count等于0望拖,系統(tǒng)才會(huì)調(diào)用dealloc真正銷毀這個(gè)對象渺尘。
3.自動(dòng)釋放池是什么,如何工作?
答:當(dāng)您向一個(gè)對象發(fā)送一個(gè)autorelease消息時(shí)说敏,Cocoa就會(huì)將該對象的一個(gè)引用放入到最新的自動(dòng)釋放池鸥跟。它仍然是個(gè)正當(dāng)?shù)膶ο螅虼俗詣?dòng)釋放池定義的作用域內(nèi)的其它對象可以向它發(fā)送消息盔沫。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí)医咨,自動(dòng)釋放池就會(huì)被釋放,池中的所有對象也就被釋放架诞。
4.autorelease的對象是在什么時(shí)候被release的拟淮?
答:autorelease實(shí)際上只是把對release的調(diào)用延遲了,對于每一個(gè)Autorelease谴忧,系統(tǒng)只是把該Object放入了當(dāng)前的Autorelease pool中很泊,當(dāng)該pool被釋放時(shí),該pool中的所有Object會(huì)被調(diào)用Release沾谓。
對于每一個(gè)Runloop委造,系統(tǒng)會(huì)隱式創(chuàng)建一個(gè)Autorelease pool,這樣所有的release pool會(huì)構(gòu)成一個(gè)象CallStack一樣的一個(gè)棧式結(jié)構(gòu)均驶,在每一個(gè)Runloop結(jié)束時(shí)昏兆,當(dāng)前棧頂?shù)腁utorelease pool會(huì)被銷毀,這樣這個(gè)pool里的每個(gè)Object(就是autorelease的對象)會(huì)被release妇穴。
5.那什么是一個(gè)Runloop呢亮垫?
一個(gè)UI事件,Timer call伟骨,delegate call饮潦,都會(huì)是一個(gè)新的Runloop。
6.以下每行代碼執(zhí)行后携狭,person對象的retain count分別是多少
Person *person = [[Person alloc] init]; count 1
[person retain]; count 2
[person release];count 1
[person release];retain count = 1;
7.下面代碼中obj2是否需要dealloc继蜡?
ClassA *obj1 = [[ClassA alloc] init];
ClassA *obj2 = obj1;
[obj1 hello]; //輸出hello
[obj1 release];
[obj2 hello]; //程序能否執(zhí)行到這一行?
[obj2 release];
答不需要他和obj2指向的是同一塊空間
8.看下面的程序,第一個(gè)NSLog會(huì)輸出什么?這時(shí)str的retainCount是多少逛腿?第二個(gè)和第三個(gè)呢稀并?為什么?
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[ary addObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@”%@%d”,str,[str retainCount]);
[ary removeAllObjects];
NSLog(@”%@%d”,str,[str retainCount]);
答:
str的retainCount創(chuàng)建+1单默,retain+1碘举,加入數(shù)組自動(dòng)+1
3
retain+1,release-1搁廓,release-1
2
數(shù)組刪除所有對象引颈,所有數(shù)組內(nèi)的對象自動(dòng)-1
1
9.autorelease和垃圾回收機(jī)制(gc)有什么關(guān)系灭贷?
答:autorelase是用代碼手寫同波,在eventloop結(jié)束后被釋放叹话。
垃圾回收機(jī)制開啟的話侮东,你只用alloc,不用release售滤,它會(huì)自動(dòng)偵測一些你不用的對象罚拟,將它release掉。
可能在實(shí)現(xiàn)方式上或者說release的時(shí)機(jī)判斷上有不同完箩,但是效果都是自動(dòng)relase這個(gè)對象赐俗。
10.IPhone OS有沒有垃圾回收(gc)?
沒有弊知。iPhone開發(fā)的時(shí)候沒有垃圾回收機(jī)制秃励,OC支持gc,但只限制在Mac OS上吉捶。
11.這段代碼有什么問題,如何修改
for (int i = 0; i < someLargeNumber; i++)
{
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@“%@”, string);
}
答:同時(shí)生成了大量autorelease對象,不利于內(nèi)存管理皆尔。但是如果放在子線程的話呐舔,而且沒有開啟垃圾回收機(jī)制的話,則會(huì)造成內(nèi)存泄露慷蠕。
修改一:
for(int i = 0; i
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
[pool1 drain];
}
修改二:
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
for(int i = 0; i
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
}
[pool1 drain];
一點(diǎn)說明:
修改一的autoreleasePool的建立方法是考慮在如果每次循環(huán)生成大量的autorelease對象,這些對象占用很大內(nèi)存的情況下珊拼,循環(huán)了1000次,那么這些所有的內(nèi)存加起來就已經(jīng)夠程序崩潰了流炕,那么這時(shí)候加在循環(huán)里面可以避免程序崩潰澎现。
但是如果程序循環(huán)1000次生成的內(nèi)存也不是很多,則可以用方法二每辟,提高效率剑辫。
[pool drain]和[pool release]在沒有垃圾回收機(jī)制的情況下,他們的效果是一樣的渠欺。但是如果做mac開發(fā)而且開啟了垃圾回收機(jī)制的話妹蔽,要用drain而不是release,因?yàn)槟欠N情況下用release只是把pool這個(gè)對象清理了挠将,而pool里面的對象是沒有被清理掉的胳岂。
附:CoreFoundation部分
1)create,copy會(huì)形成own關(guān)系,不需要時(shí)應(yīng)該CFRelease();
2) get方式得到的object舔稀,不形成own關(guān)系乳丰,不需要管理;
3)一個(gè)object作為參數(shù)傳遞到函數(shù)中后内贮,receiver不與他形成own關(guān)系产园,也就是可能在任何時(shí)間被deallocate掉汞斧,所以需要CFRetain();
4)CFIndex count = CFGetRetainCount(obj)淆两;
5) myCFObj1 = myCFObj2-->引用拷貝断箫,不會(huì)生成2個(gè)對象,應(yīng)該使用CFStringCreatCopy()
6)符合的CF對象秋冰,copy時(shí)需要自己實(shí)現(xiàn)deep copy仲义;
八、CocoaTouch
1.main.m中都發(fā)生了什么?
答:程序入口剑勾,創(chuàng)建自動(dòng)釋放池埃撵,創(chuàng)建應(yīng)用程序?qū)ο螅?dòng)其主循環(huán)虽另,運(yùn)行程序暂刘,釋放程序運(yùn)行期間得所有加入自動(dòng)釋放池的對象。
2.int retVal = UIApplicationMain(argc, argv, nil, nil);是什么意思捂刺?
答:對UIApplication對象進(jìn)行了初始化谣拣,這個(gè)方法除了argc和argv參數(shù)外,另外這個(gè)函數(shù)還有兩個(gè)字符串參數(shù)來識別UIApplication類和UIApplication代理類族展,在這里默認(rèn)是2個(gè)nil,第一個(gè)參數(shù)為nil就默認(rèn)把UIApplication類作為缺省值進(jìn)行初始化森缠,可以在這里不填nil而是使用自己定義的UIApplication子類。至于第二個(gè)參數(shù)nil就設(shè)置為nil就把模板生成的HelloWorldAppdelegate類作為默認(rèn)值仪缸。
3.編寫NSArray的setter和getter.
答:getter比較容易贵涵,直接返回NSArray的指針就可以了,
setter注意每個(gè)元素加進(jìn)去得時(shí)候需要retain一次恰画。
4.什么是Notification宾茂?答:觀察者模式,controller向defaultNotificationCenter添加自己的notification拴还,其他類注冊這個(gè)notification就可以收到通知跨晴,這些類可以在收到通知時(shí)做自己的操作(多觀察者默認(rèn)隨機(jī)順序發(fā)通知給觀察者們,而且每個(gè)觀察者都要等當(dāng)前的某個(gè)觀察者的操作做完才能輪到他來操作片林,可用NotificationQueue的方式安排觀察者的反應(yīng)順序坟奥,也可以在添加觀察者中設(shè)定反映時(shí)間,取消觀察需要在viewDidUnload跟dealloc中都要注銷)拇厢。
5.多線程編程中爱谁,NSThread子線程與主線程的交互.
答:子線程內(nèi)執(zhí)行[self performSelectorOnMainThread:@selector(function:)withObject:];通知主線程執(zhí)行相應(yīng)方法⌒①耍或者用全局變量的方式访敌。
6.objective-c中是所有對象間的交互是如何實(shí)現(xiàn)的?(深圳皆凱科技有限公司筆試題)
答:在Objective-C中所有對象間的交互都是通過指針實(shí)現(xiàn)的,確切的說話衣盾,叫做發(fā)送消息寺旺。
8.objective-c中是如何實(shí)現(xiàn)線程同步的?
答:關(guān)鍵字@synchronized()
7.id聲明的對象有什么特性爷抓?
答:id聲明的對象具有運(yùn)行時(shí)的特性,即可以指向任意類型的objcetive-c的對象阻塑;
8.cocoa touch框架
iPhone OS應(yīng)用程序的基礎(chǔ)Cocoa Touch框架重用了許多Mac系統(tǒng)的成熟模式蓝撇,但是它更多地專注于觸摸的接口和優(yōu)化。UIKit為您提供了在iPhone OS上實(shí)現(xiàn)圖形陈莽,事件驅(qū)動(dòng)程序的基本工具渤昌,其建立在和Mac OS X中一樣的Foundation框架上,包括文件處理走搁,網(wǎng)絡(luò)独柑,字符串操作等。
Cocoa Touch具有和iPhone用戶接口一致的特殊設(shè)計(jì)私植。有了UIKit忌栅,您可以使用iPhone OS上的獨(dú)特的圖形接口控件,按鈕曲稼,以及全屏視圖的功能索绪,您還可以使用加速儀和多點(diǎn)觸摸手勢來控制您的應(yīng)用。
各色俱全的框架除了UIKit外贫悄,Cocoa Touch包含了創(chuàng)建世界一流iPhone應(yīng)用程序需要的所有框架瑞驱,從三維圖形,到專業(yè)音效清女,甚至提供設(shè)備訪問API以控制攝像頭,或通過GPS獲知當(dāng)前位置晰筛。Cocoa Touch既包含只需要幾行代碼就可以完成全部任務(wù)的強(qiáng)大的Objective-C框架嫡丙,也在需要時(shí)提供基礎(chǔ)的C語言API來直接訪問系統(tǒng)。這些框架包括:
Core Animation
通過Core Animation读第,您就可以通過一個(gè)基于組合獨(dú)立圖層的簡單的編程模型來創(chuàng)建豐富的用戶體驗(yàn)曙博。
Core Audio
Core Audio是播放,處理和錄制音頻的專業(yè)技術(shù)怜瞒,能夠輕松為您的應(yīng)用程序添加強(qiáng)大的音頻功能父泳。
Core Data
提供了一個(gè)面向?qū)ο蟮臄?shù)據(jù)管理解決方案,它易于使用和理解吴汪,甚至可處理任何應(yīng)用或大或小的數(shù)據(jù)模型惠窄。
功能列表:框架分類
下面是Cocoa Touch中一小部分可用的框架:
音頻和視頻
Core Audio
OpenAL
Media Library
AV Foundation
數(shù)據(jù)管理
Core Data
SQLite
圖形和動(dòng)畫
Core Animation
OpenGL ES
Quartz 2D
網(wǎng)絡(luò)/li>
Bonjour
WebKit
BSD Sockets
用戶應(yīng)用
Address Book
Core Location
Map Kit
Store Kit
九、設(shè)計(jì)模式
1.MVC模式的理解
MVC設(shè)計(jì)模式考慮三種對象:模型對象漾橙、視圖對象杆融、和控制器對象。模型對象代表特別的知識和專業(yè)技能霜运,它們負(fù)責(zé)保有應(yīng)用程序的數(shù)據(jù)和定義操作數(shù)據(jù)的邏輯脾歇。視圖對象知道如何顯示應(yīng)用程序的模型數(shù)據(jù)蒋腮,而且可能允許用戶對其進(jìn)行編輯∨焊鳎控制器對象是應(yīng)用程序的視圖對象和模型對象之間的協(xié)調(diào)者池摧。
2.描述一下iOS SDK中如何實(shí)現(xiàn)MVC的開發(fā)模式
MVC是模型、視圖激况、控制開發(fā)模式作彤,對于iOS SDK,所有的View都是視圖層的誉碴,它應(yīng)該獨(dú)立于模型層宦棺,由視圖控制層來控制。所有的用戶數(shù)據(jù)都是模型層黔帕,它應(yīng)該獨(dú)立于視圖代咸。所有的ViewController都是控制層,由它負(fù)責(zé)控制視圖成黄,訪問模型數(shù)據(jù)呐芥。
3.類工廠方法是什么
類工廠方法的實(shí)現(xiàn)是為了向客戶提供方便,它們將分配和初始化合在一個(gè)步驟中奋岁,返回被創(chuàng)建的對象思瘟,并進(jìn)行自動(dòng)釋放處理。這些方法的形式是+ (type)className…(其中className不包括任何前綴)闻伶。
工廠方法可能不僅僅為了方便使用滨攻。它們不但可以將分配和初始化合在一起,還可以為初始化過程提供對象的分配信息蓝翰。
類工廠方法的另一個(gè)目的是使類(比如NSWorkspace)提供單件實(shí)例光绕。雖然init…方法可以確認(rèn)一個(gè)類在每次程序運(yùn)行過程只存在一個(gè)實(shí)例,但它需要首先分配一個(gè)“生的”實(shí)例畜份,然后還必須釋放該實(shí)例诞帐。
工廠方法則可以避免為可能沒有用的對象盲目分配內(nèi)存。
4.單件實(shí)例是什么
Foundation和Application Kit框架中的一些類只允許創(chuàng)建單件對象爆雹,即這些類在當(dāng)前進(jìn)程中的唯一實(shí)例停蕉。舉例來說,NSFileManager和NSWorkspace類在使用時(shí)都是基于進(jìn)程進(jìn)行單件對象的實(shí)例化钙态。當(dāng)向這些類請求實(shí)例的時(shí)候慧起,它們會(huì)向您傳遞單一實(shí)例的一個(gè)引用,如果該實(shí)例還不存在册倒,則首先進(jìn)行實(shí)例的分配和初始化完慧。單件對象充當(dāng)控制中心的角色,負(fù)責(zé)指引或協(xié)調(diào)類的各種服務(wù)。如果類在概念上只有一個(gè)實(shí)例(比如
NSWorkspace)屈尼,就應(yīng)該產(chǎn)生一個(gè)單件實(shí)例册着,而不是多個(gè)實(shí)例;如果將來某一天可能有多個(gè)實(shí)例脾歧,您可以使用單件實(shí)例機(jī)制甲捏,而不是工廠方法或函數(shù)。
十鞭执、操作系統(tǒng)
1.線程與進(jìn)程的區(qū)別和聯(lián)系?
答:進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元司顿,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性。
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式兄纺。進(jìn)程有獨(dú)立的地址空間大溜,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對其它進(jìn)程產(chǎn)生影響估脆,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑钦奋。線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間疙赠,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉付材,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí)圃阳,耗費(fèi)資源較大厌衔,效率要差一些。但對于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作捍岳,只能用線程富寿,不能用進(jìn)程。
2.列舉幾種進(jìn)程的同步機(jī)制锣夹,并比較其優(yōu)缺點(diǎn)页徐。
答案:原子操作信號量機(jī)制自旋鎖管程,會(huì)合晕城,分布式系統(tǒng)
進(jìn)程之間通信的途徑
答案:共享存儲(chǔ)系統(tǒng)消息傳遞系統(tǒng)管道:以文件系統(tǒng)為基礎(chǔ)
進(jìn)程死鎖的原因
答案:資源競爭及進(jìn)程推進(jìn)順序非法
死鎖的4個(gè)必要條件
答案:互斥泞坦、請求保持窖贤、不可剝奪砖顷、環(huán)路
死鎖的處理
答案:鴕鳥策略、預(yù)防策略赃梧、避免策略滤蝠、檢測與解除死鎖
3.堆和棧的區(qū)別
管理方式:對于棧來講,是由編譯器自動(dòng)管理授嘀,無需我們手工控制物咳;對于堆來說,釋放工作由程序員控制蹄皱,容易產(chǎn)生memory leak览闰。
申請大行痉簟:
棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域压鉴。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的崖咨,在WINDOWS下,棧的大小是2M(也有的說是1M油吭,總之是一個(gè)編譯時(shí)就確定的常數(shù))击蹲,如果申請的空間超過棧的剩余空間時(shí),將提示overflow婉宰。因此歌豺,能從棧獲得的空間較小。
堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)心包,是不連續(xù)的內(nèi)存區(qū)域类咧。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的谴咸,而鏈表的遍歷方向是由低地址向高地址轮听。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見岭佳,堆獲得的空間比較靈活血巍,也比較大。
碎片問題:對于堆來講珊随,頻繁的new/delete勢必會(huì)造成內(nèi)存空間的不連續(xù)述寡,從而造成大量的碎片,使程序效率降低叶洞。對于棧來講鲫凶,則不會(huì)存在這個(gè)問題,因?yàn)闂J窍冗M(jìn)后出的隊(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ì)在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行亿眠,這就決定了棧的效率比較高碎罚。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的纳像。
十一魂莫、雜項(xiàng)
1.動(dòng)態(tài)綁定
—在運(yùn)行時(shí)確定要調(diào)用的方法
動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。在編譯時(shí)爹耗,方法的調(diào)用并不和代碼綁定在一起耙考,只有在消實(shí)發(fā)送出來之后,才確定被調(diào)用的代碼潭兽。通過動(dòng)態(tài)類型和動(dòng)態(tài)綁定技術(shù)倦始,您的代碼每次執(zhí)行都可以得到不同的結(jié)果。運(yùn)行時(shí)因子負(fù)責(zé)確定消息的接收者和被調(diào)用的方法山卦。運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持鞋邑。當(dāng)您向一個(gè)動(dòng)態(tài)類型確定了的對象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會(huì)通過接收者的isa指針定位對象的類账蓉,并以此為起點(diǎn)確定被調(diào)用的方法枚碗,方法和消息是動(dòng)態(tài)綁定的。而且铸本,您不必在Objective-C代碼中做任何工作肮雨,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。您在每次發(fā)送消息時(shí)箱玷,
特別是當(dāng)消息的接收者是動(dòng)態(tài)類型已經(jīng)確定的對象時(shí)怨规,動(dòng)態(tài)綁定就會(huì)例行而透明地發(fā)生。
2.目標(biāo)-動(dòng)作機(jī)制
目標(biāo)是動(dòng)作消息的接收者锡足。一個(gè)控件波丰,或者更為常見的是它的單元,以插座變量(參見”插座變量”部分)的形式保有其動(dòng)作消息的目標(biāo)舶得。
動(dòng)作是控件發(fā)送給目標(biāo)的消息掰烟,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法沐批。
程序需要某些機(jī)制來進(jìn)行事件和指令的翻譯纫骑。這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制。
3.什么是鍵-值,鍵路徑是什么
模型的性質(zhì)是通過一個(gè)簡單的鍵(通常是個(gè)字符串)來指定的珠插。視圖和控制器通過鍵來查找相應(yīng)的屬性值惧磺。在一個(gè)給定的實(shí)體中颖对,同一個(gè)屬性的所有值具有相同的數(shù)據(jù)類型捻撑。鍵-值編碼技術(shù)用于進(jìn)行這樣的查找—它是一種間接訪問對象屬性的機(jī)制。
鍵路徑是一個(gè)由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個(gè)連接在一起的對象性質(zhì)序列顾患。第一個(gè)鍵的性質(zhì)是由先前的性質(zhì)決定的番捂,接下來每個(gè)鍵的值也是相對于其前面的性質(zhì)。鍵路徑使您可以以獨(dú)立于模型實(shí)現(xiàn)的方式指定相關(guān)對象的性質(zhì)江解。通過鍵路徑设预,您可以指定對象圖中的一個(gè)任意深度的路徑,使其指向相關(guān)對象的特定屬性犁河。
4.什么時(shí)候用delegate鳖枕,什么時(shí)候用Notification?
答:delegate針對one-to-one關(guān)系桨螺,并且reciever可以返回值給sender宾符,
notification可以針對one-to-one/many/none,reciever無法返回值給sender.
所以,delegate用于sender希望接受到reciever的某個(gè)功能反饋值灭翔,notification用于通知多個(gè)object某個(gè)事件魏烫。
5.什么是KVC和KVO?
答:KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):一個(gè)對象在調(diào)用setValue的時(shí)候肝箱,(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán)境參數(shù)哄褒。(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口煌张。(3)再直接查找得來的具體的方法實(shí)現(xiàn)呐赡。
KVO(Key-Value-Observing):當(dāng)觀察者為一個(gè)對象的屬性進(jìn)行了注冊,被觀察對象的isa指針被修改的時(shí)候骏融,isa指針就會(huì)指向一個(gè)中間類罚舱,而不是真實(shí)的類。所以isa指針其實(shí)不需要指向?qū)嵗龑ο笳鎸?shí)的類绎谦。所以我們的程序最好不要依賴于isa指針管闷。在調(diào)用類的方法的時(shí)候,最好要明確對象實(shí)例的類名窃肠。
其它回答:
kvc就是key value coding包个,簡而言之就是根據(jù)key值改變它的內(nèi)容,我覺得很類似于dictionary冤留。
kvo就是Key Value Observing碧囊,就是相當(dāng)于你監(jiān)控特定對象的特定key,當(dāng)key對應(yīng)的值發(fā)生改變時(shí)纤怒,會(huì)觸發(fā)它的對應(yīng)方法糯而。
kvc實(shí)現(xiàn)(NSKeyValueCoding Protocol),最簡單的方法就是setValue: forKey:以及valueForKey:方法泊窘。例如你實(shí)現(xiàn)一個(gè)Person類熄驼,有兩個(gè)property name像寒,age,生成一個(gè)新對象p瓜贾,可以用[p setValue:@"Solomon" forKey:@"name"];這樣的方法進(jìn)行賦值诺祸。
kvo實(shí)現(xiàn)(NSKeyValueObserving Protocol),–addObserver:forKeyPath:options:context:對你想要監(jiān)控的對象祭芦,想要監(jiān)控的屬性添加一個(gè)observe筷笨,當(dāng)值改變時(shí),會(huì)觸發(fā)– willChangeValueForKey:等方法龟劲。
kvc kvo結(jié)合使用胃夏,可以當(dāng)作對對象屬性值進(jìn)行監(jiān)控的一個(gè)notification,它對值進(jìn)行監(jiān)控昌跌。而notification也同時(shí)可以對消息響應(yīng)之類做出監(jiān)控构订。
簡單說KVC就是一個(gè)實(shí)現(xiàn)并擴(kuò)展了setter/getter的方法集。
6.Notification和KVO有什么不同避矢?
KVO就是給屬性添加一個(gè)監(jiān)控器悼瘾,當(dāng)值發(fā)生改變的時(shí)候,給你一個(gè)接口去處理它审胸。textView用過吧亥宿,當(dāng)textView的值改變時(shí),不也有一個(gè)textViewDidChange:的delegate方法么砂沛?
它就是一個(gè)NSObject的protocol烫扼,本來就是一個(gè)很簡單的東西,不要想的很復(fù)雜化碍庵。這些東西的提出只是為了更方便映企,而不是它有什么特殊的含義,正如MVC一樣静浴。
notification也就是在程序檢測event的loop里面加上一個(gè)跟蹤事件的判斷堰氓,如果接收到了這個(gè)事件,則做自己想要去做的事情苹享。比如一個(gè)uiview的對象接收到一個(gè)觸摸事件双絮,它在系統(tǒng)檢測event的無限循環(huán)里接收到了它,然后返回一個(gè)uitouch的事件讓你去處理得问,從根本上來說它和notification的性質(zhì)一樣的囤攀,雖然可能實(shí)現(xiàn)方式不盡相同,但是總歸是跳不出這個(gè)圈子的宫纬。
當(dāng)然焚挠,再往底層的東西,怎么去傳遞notification之類漓骚,蘋果封裝好了蝌衔,你也不可能知道榛泛。就算你是蘋果的程序員,由你來實(shí)現(xiàn)胚委,也可能有不同的方式來達(dá)到同樣的目的。而這個(gè)已經(jīng)超出了sdk編程的范圍叉信。