IOS_OC_id ,NSObject, idlt;NSObjectgt;差别
生活随笔
收集整理的這篇文章主要介紹了
IOS_OC_id ,NSObject, idlt;NSObjectgt;差别
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
我們常常會(huì)混淆下面三種申明(我是沒有留意過):
????1. id foo1;
????2. NSObject *foo2;
????3. id<NSObject> foo3;
????第一種是最經(jīng)常使用的,它簡(jiǎn)單地申明了指向?qū)ο蟮闹羔?#xff0c;沒有給編譯器不論什么類型信息,因此,編譯器不會(huì)做類型檢查。但也由于是這樣,你能夠發(fā)送不論什么信息給id類型的對(duì)象。這就是為什么+alloc返回id類型,但調(diào)用[[Foo alloc] init]不會(huì)產(chǎn)生編譯錯(cuò)誤。
????因此,id類型是執(zhí)行時(shí)的動(dòng)態(tài)類型,編譯器無法知道它的真實(shí)類型,即使你發(fā)送一個(gè)id類型沒有的方法,也不會(huì)產(chǎn)生編譯警告。
????我們知道,id類型是一個(gè)Objective-C對(duì)象,但并非都指向繼承自NSOjbect的對(duì)象,即使這個(gè)類型和NSObject對(duì)象有非常多共同的方法,像retain和release。要讓編譯器知道這個(gè)類繼承自NSObject,一種解決的方法就是像第2種那樣,使用NSObject靜態(tài)類型,當(dāng)你發(fā)送NSObject沒有的方法,像length或者count時(shí),編譯器就會(huì)給出警告。這也意味著,你能夠安全地使用像retain,release,description這些方法。
????因此,申明一個(gè)通用的NSObject對(duì)象指針和你在其他語言里做的類似,像java,但其他語言有一定的限制,沒有像Objective-C這樣靈活。并非全部的Foundation/Cocoa對(duì)象都繼承息NSObject,比方NSProxy就不從NSObject繼承,所以你無法使用NSObject*指向這個(gè)對(duì)象,即使NSProxy對(duì)象有release和retain這種通用方法。為了解決問題,這時(shí)候,你就須要一個(gè)指向擁有NSObject方法對(duì)象的指針,這就是第3種申明的使用情景。
????id告訴編譯器,你不關(guān)心對(duì)象是什么類型,但它必須遵守NSObject協(xié)議(protocol),編譯器就能保證全部賦值給id類型的對(duì)象都遵守NSObject協(xié)議(protocol)。這種指針能夠指向不論什么NSObject對(duì)象,由于NSObject對(duì)象遵守NSObject協(xié)議(protocol),并且,它也能夠用來保存NSProxy對(duì)象,由于它也遵守NSObject協(xié)議(protocol)。這是很強(qiáng)大,方便且靈活,你不用關(guān)心對(duì)象是什么類型,而僅僅關(guān)心它實(shí)現(xiàn)了哪些方法。
????如今你知道你要用什么類型了不?
????假設(shè)你不須要不論什么的類型檢查,使用id,它常常作為返回類型,也常常常使用于申明代理(delegate)類型。由于代理類型通常在執(zhí)行時(shí),才會(huì)檢查是否實(shí)現(xiàn)了那些方法。
????假設(shè)真的須要編譯器檢查,那你就考慮使用第2種或者第3種。非常少看到NSObject*能正常執(zhí)行,但id無法正常執(zhí)行的。使用協(xié)議(protocol)的長(zhǎng)處是,它能指向NSProxy對(duì)象,而更經(jīng)常使用的情況是,你僅僅想知道某個(gè)對(duì)象遵守了哪個(gè)協(xié)議,而不用關(guān)心它是什么類型。
????1. id foo1;
????2. NSObject *foo2;
????3. id<NSObject> foo3;
????第一種是最經(jīng)常使用的,它簡(jiǎn)單地申明了指向?qū)ο蟮闹羔?#xff0c;沒有給編譯器不論什么類型信息,因此,編譯器不會(huì)做類型檢查。但也由于是這樣,你能夠發(fā)送不論什么信息給id類型的對(duì)象。這就是為什么+alloc返回id類型,但調(diào)用[[Foo alloc] init]不會(huì)產(chǎn)生編譯錯(cuò)誤。
????因此,id類型是執(zhí)行時(shí)的動(dòng)態(tài)類型,編譯器無法知道它的真實(shí)類型,即使你發(fā)送一個(gè)id類型沒有的方法,也不會(huì)產(chǎn)生編譯警告。
????我們知道,id類型是一個(gè)Objective-C對(duì)象,但并非都指向繼承自NSOjbect的對(duì)象,即使這個(gè)類型和NSObject對(duì)象有非常多共同的方法,像retain和release。要讓編譯器知道這個(gè)類繼承自NSObject,一種解決的方法就是像第2種那樣,使用NSObject靜態(tài)類型,當(dāng)你發(fā)送NSObject沒有的方法,像length或者count時(shí),編譯器就會(huì)給出警告。這也意味著,你能夠安全地使用像retain,release,description這些方法。
????因此,申明一個(gè)通用的NSObject對(duì)象指針和你在其他語言里做的類似,像java,但其他語言有一定的限制,沒有像Objective-C這樣靈活。并非全部的Foundation/Cocoa對(duì)象都繼承息NSObject,比方NSProxy就不從NSObject繼承,所以你無法使用NSObject*指向這個(gè)對(duì)象,即使NSProxy對(duì)象有release和retain這種通用方法。為了解決問題,這時(shí)候,你就須要一個(gè)指向擁有NSObject方法對(duì)象的指針,這就是第3種申明的使用情景。
????id告訴編譯器,你不關(guān)心對(duì)象是什么類型,但它必須遵守NSObject協(xié)議(protocol),編譯器就能保證全部賦值給id類型的對(duì)象都遵守NSObject協(xié)議(protocol)。這種指針能夠指向不論什么NSObject對(duì)象,由于NSObject對(duì)象遵守NSObject協(xié)議(protocol),并且,它也能夠用來保存NSProxy對(duì)象,由于它也遵守NSObject協(xié)議(protocol)。這是很強(qiáng)大,方便且靈活,你不用關(guān)心對(duì)象是什么類型,而僅僅關(guān)心它實(shí)現(xiàn)了哪些方法。
????如今你知道你要用什么類型了不?
????假設(shè)你不須要不論什么的類型檢查,使用id,它常常作為返回類型,也常常常使用于申明代理(delegate)類型。由于代理類型通常在執(zhí)行時(shí),才會(huì)檢查是否實(shí)現(xiàn)了那些方法。
????假設(shè)真的須要編譯器檢查,那你就考慮使用第2種或者第3種。非常少看到NSObject*能正常執(zhí)行,但id無法正常執(zhí)行的。使用協(xié)議(protocol)的長(zhǎng)處是,它能指向NSProxy對(duì)象,而更經(jīng)常使用的情況是,你僅僅想知道某個(gè)對(duì)象遵守了哪個(gè)協(xié)議,而不用關(guān)心它是什么類型。
轉(zhuǎn)載于:https://www.cnblogs.com/bhlsheji/p/4236368.html
總結(jié)
以上是生活随笔為你收集整理的IOS_OC_id ,NSObject, idlt;NSObjectgt;差别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 读写日志文件
- 下一篇: 消息断点 RUN跟踪