1.NSObject包含了一些其他的方法全蝶,需要實(shí)現(xiàn)NSObject協(xié)議悼枢,可以用NSObject來(lái)表示id锄开,但是不能用id來(lái)表示NSObject
2.id關(guān)鍵字在編譯的時(shí)候不會(huì)被檢查炒刁,而NSObject在編譯的時(shí)候被被檢查是否含有一些錯(cuò)誤的方法
3.id可以是任何對(duì)象坠七,包括不是NSObject的對(duì)象
4.定義id的時(shí)候不需要*见转,而定義NSOject的時(shí)候需要命雀。
網(wǎng)站:http://blog.csdn.net/linjinxing/article/details/9994903
如下:
1. id foo1;
2.NSObject *foo2;
3.id<NSObject>?foo3;
第一種是最常用,它簡(jiǎn)單地申明了指向?qū)ο蟮闹羔樥扼铮瑳](méi)有給編譯器任何類(lèi)型信息吏砂,因此,編譯器不會(huì)做類(lèi)型檢查乘客。但也因?yàn)槭沁@樣狐血,你可以發(fā)送任何信息給id類(lèi)型的對(duì)象。這就是為什么+alloc返回id類(lèi)型易核,但調(diào)用[[Foo alloc] init]不會(huì)產(chǎn)生編譯錯(cuò)誤匈织。
因此,id類(lèi)型是運(yùn)行時(shí)的動(dòng)態(tài)類(lèi)型牡直,編譯器無(wú)法知道它的真實(shí)類(lèi)型缀匕,即使你發(fā)送一個(gè)id類(lèi)型沒(méi)有的方法,也不會(huì)產(chǎn)生編譯警告碰逸。
我們知道乡小,id類(lèi)型是一個(gè)Objective-C對(duì)象,但并不是都指向繼承自NSOjbect的對(duì)象饵史,即使這個(gè)類(lèi)型和NSObject對(duì)象有很多共同的方法满钟,像retain和release。要讓編譯器知道這個(gè)類(lèi)繼承自NSObject胳喷,一種解決辦法就是像第2種那樣湃番,使用NSObject靜態(tài)類(lèi)型,當(dāng)你發(fā)送NSObject沒(méi)有的方法吭露,像length或者count時(shí)吠撮,編譯器就會(huì)給出警告。這也意味著奴饮,你可以安全地使用像retain纬向,release,description這些方法戴卜。
因此逾条,申明一個(gè)通用的NSObject對(duì)象指針和你在其它語(yǔ)言里做的類(lèi)似,像Java投剥,但其它語(yǔ)言有一定的限制师脂,沒(méi)有像Objective-C這樣靈活。并不是所有的Foundation/Cocoa對(duì)象都繼承息NSObject,比如NSProxy就不從NSObject繼承吃警,所以你無(wú)法使用NSObject*指向這個(gè)對(duì)象糕篇,即使NSProxy對(duì)象有release和retain這樣的通用方法。為了解決這個(gè)問(wèn)題酌心,這時(shí)候拌消,你就需要一個(gè)指向擁有NSObject方法對(duì)象的指針,這就是第3種申明的使用情景安券。
id告訴編譯器墩崩,你不關(guān)心對(duì)象是什么類(lèi)型,但它必須遵守NSObject協(xié)議(protocol)侯勉,編譯器就能保證所有賦值給id類(lèi)型的對(duì)象都遵守NSObject協(xié)議(protocol)鹦筹。這樣的指針可以指向任何NSObject對(duì)象,因?yàn)镹SObject對(duì)象遵守NSObject協(xié)議(protocol)址貌,而且铐拐,它也可以用來(lái)保存NSProxy對(duì)象,因?yàn)樗沧袷豊SObject協(xié)議(protocol)练对。這是非常強(qiáng)大遍蟋,方便且靈活,你不用關(guān)心對(duì)象是什么類(lèi)型螟凭,而只關(guān)心它實(shí)現(xiàn)了哪些方法匿值。
現(xiàn)在你知道你要用什么類(lèi)型了不?
如果你不需要任何的類(lèi)型檢查赂摆,使用id,它經(jīng)常作為返回類(lèi)型钟些,也經(jīng)常用于申明代理(delegate)類(lèi)型烟号。因?yàn)榇眍?lèi)型通常在運(yùn)行時(shí),才會(huì)檢查是否實(shí)現(xiàn)了那些方法政恍。
如果真的需要編譯器檢查汪拥,那你就考慮使用第2種或者第3種。很少看到NSObject*能正常運(yùn)行篙耗,但id無(wú)法正常運(yùn)行的迫筑。使用協(xié)議(protocol)的優(yōu)點(diǎn)是,它能指向NSProxy對(duì)象宗弯,而更常用的情況是脯燃,你只想知道某個(gè)對(duì)象遵守了哪個(gè)協(xié)議,而不用關(guān)心它是什么類(lèi)型蒙保。
補(bǔ)充:使用id<NSObject>來(lái)聲明一個(gè)對(duì)象辕棚,相當(dāng)于告訴編譯我們并不知道這個(gè)對(duì)象的類(lèi)型,但是它實(shí)現(xiàn)NSObject protocol。一個(gè)這種類(lèi)型的指針逝嚎,即可以用來(lái)指向NSObject*對(duì)象扁瓢,也可以用來(lái)指向NSProxy*對(duì)象,因?yàn)镹SObject對(duì)象與NSProxy對(duì)象都是現(xiàn)了NSObject protocol