在IOS的學(xué)習(xí)中,估計(jì)很多開(kāi)發(fā)人員容易上手,但真正內(nèi)部結(jié)構(gòu),我想理解起來(lái)也是比較費(fèi)勁,因?yàn)镮OS開(kāi)發(fā)并不是一門(mén)開(kāi)源語(yǔ)言,語(yǔ)言的基礎(chǔ)架構(gòu),有一些部分不凡多做些猜想驗(yàn)證,并通過(guò)蘋(píng)果官方文檔求證,接下來(lái)按自己的理解將OC基礎(chǔ)語(yǔ)言的3個(gè)陷阱進(jìn)行講解;
1. MRC模式,NSString進(jìn)行retainCount的值:
根據(jù)蘋(píng)果的官方文檔上面寫(xiě)著應(yīng)該返回的是這個(gè)對(duì)象的UINTMAX_MAX, 并且不會(huì)釋放,這個(gè)UINTMAX_MAX是最大十六進(jìn)制(0xffffffffffffffff)
如果你當(dāng)成有符號(hào)數(shù)取補(bǔ)碼后輸出就得-1;
如果你當(dāng)成無(wú)符號(hào)數(shù)就是最大數(shù)即:18446744073709551615
這是因?yàn)樽址a(chǎn)生的對(duì)象是屬于autorelease pool,在幫助文檔中可以看到這么一句話(huà):
The retainCount method does not account for any pending autorelease messages send to the receiver.
就是說(shuō)retainCount對(duì)于autorelease消息產(chǎn)生的的對(duì)象,并不可靠。
Do not use this method. (required) You should never use-retainCount, because it never tells you anything useful.
永遠(yuǎn)不要用這個(gè)方法,只要遵守alloc,retain或copy以及任何需要分配內(nèi)存的時(shí)候調(diào)用release就可以了
2. Property中的strong與weak
在ARC模式下有兩種Property的屬性參數(shù)用于修飾自定義對(duì)象,strong和weak;這兩個(gè)參數(shù)的用法如下:
strong :強(qiáng)引用,指針對(duì)對(duì)象具有決定的占有
weak : 弱引用,指針對(duì)對(duì)象不具有決定的占有
這兩個(gè)屬性參數(shù)的用法,通常是在開(kāi)發(fā)中不容易理解一個(gè)問(wèn)題,舉個(gè)生活中的實(shí)例:
如果有5個(gè)人都牽著這一條狗(5條繩子栓一只狗) ,相當(dāng)于 5個(gè)strong類(lèi)型指針指向一個(gè)對(duì)象。
除非5個(gè)繩子都脫落(也就是5個(gè)strong指針都=nil,則該對(duì)象釋放),否則狗是不會(huì)跑掉的;
weak型指針就像是一個(gè)小孩子指著狗喊道:“看,有一只狗在那里”,只要狗一直被拴著,那么小孩子就能看到狗(weak指針)會(huì)一直指向它,只要狗的繩子脫落,那么狗就會(huì)跑掉,不管有多少的小孩在看著它。
在使用場(chǎng)合中,一般情況下,我們都使用strong;特殊情況如,在協(xié)議代理與IBOutlet控件的映射,我們使用weak屬性參數(shù)作修飾;因?yàn)镮BOutlet的屬性為weak,是因?yàn)樗呀?jīng)被view引用了,除非view被釋放,否則IBOutlet的屬性也不會(huì)被釋放,另外IBOutlet屬性的生命周期和view應(yīng)該是一致的,所以IBOutlet屬性一般設(shè)為weak。
參考官方文檔如下: From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.
The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet)。
簡(jiǎn)單的說(shuō),如果IBOutlet對(duì)象是nib/sb scene的擁有者(File’s owner)所持有的對(duì)象,那么很顯然擁有者必須“擁有”對(duì)象的指針,因此屬性應(yīng)設(shè)置為strong。而其他的
IBOutlet對(duì)象的屬性需要設(shè)置為weak,因?yàn)閾碛姓卟⒉恍枰皳碛小彼麄兊闹羔槨Ee例來(lái)說(shuō),UIViewController的view屬性是strong,因?yàn)閏ontroller要直接擁有view。而添加到view上的subviews,作為IBOutlet只需要設(shè)置為weak就可以了,因?yàn)樗麄儾皇莄ontroller直接擁有的。直接擁有subviews的是controller的view,
3.自定義對(duì)象拷貝的過(guò)程
在ARC模式中,使用自定義的對(duì)象進(jìn)行copy,我們知道會(huì)出現(xiàn)程序奔潰,關(guān)于奔潰的原因,我們可通過(guò)字符串的copy進(jìn)行分析;使用字符串對(duì)象進(jìn)行copy系統(tǒng)不會(huì)出現(xiàn)奔潰;且字符串中與自定義對(duì)象所在類(lèi)一樣,并沒(méi)有copy的方法,由此可知,都是調(diào)用的是父類(lèi)NSObject的的copy,由此產(chǎn)生了疑問(wèn):
疑問(wèn):NSString與自定義對(duì)象都是調(diào)NSObject的方法,要報(bào)錯(cuò)的話(huà)NSString也同樣會(huì)報(bào)錯(cuò)
分析1:NSString類(lèi)遵守了NSCopying協(xié)議:從而可知,NSString中一定實(shí)現(xiàn)了協(xié)議中必須的方法:copyWithZone
分析2: 我們可做一個(gè)猜想,字符串調(diào)用copy方法,必定內(nèi)部調(diào)用了copyWithZone,字符串中有這個(gè)copyWithZone的實(shí)現(xiàn)方法所以不會(huì)奔潰;然而,自定義類(lèi)因?yàn)闆](méi)有實(shí)現(xiàn)協(xié)議方法,所以copy方法的實(shí)現(xiàn)部分調(diào)用copyWithZone會(huì)導(dǎo)致奔潰;
分析3: 通過(guò)驗(yàn)證法求證,自定義對(duì)象調(diào)用copy方法,內(nèi)部也會(huì)調(diào)用了copyWithZone;用自定義類(lèi)遵守NSCopying,然后實(shí)現(xiàn)copyWithZone的方法;
結(jié)論:在完成分析3的操作后,執(zhí)行程序并沒(méi)有出現(xiàn)程序奔潰;證明我們進(jìn)行的推論正確,實(shí)質(zhì)自定義代理對(duì)象的拷貝過(guò)程是通過(guò)協(xié)議代理完成;在以后我們學(xué)習(xí)的過(guò)程中,經(jīng)常會(huì)碰到類(lèi)似的通過(guò)協(xié)議代理暴露更多接口的設(shè)計(jì)模式,包括自定義的協(xié)議代理與系統(tǒng)提供的協(xié)議代理:
a.自定義的協(xié)議代理有完成的操作步驟: (1) 定制一張協(xié)議,在協(xié)議中聲明協(xié)議方法
?。?) 被代理者:聲明委托代理對(duì)象;指派委托代理對(duì)象去調(diào)用代理協(xié)議方法
?。?) 代理者:遵守協(xié)議;實(shí)現(xiàn)協(xié)議方法;設(shè)置代理對(duì)象(將代理對(duì)象傳入被代理者聲明的委托代理對(duì)象中)
b.系統(tǒng)統(tǒng)提供的協(xié)議代理分為兩個(gè)部分:(以自定義拷貝對(duì)象為例) 第一部分:系統(tǒng)已生成的部分: (1)。 系統(tǒng)定制協(xié)議:NSCopying (2)。 被代理者:NSObject 第二部分:開(kāi)發(fā)者需完成的部分
?。?)。 代理者:遵守協(xié)議,實(shí)現(xiàn)協(xié)議方法,(隱含設(shè)置代理)
C語(yǔ)言和OC和C++的區(qū)別
答:c語(yǔ)言是面向過(guò)程的,OC是面向?qū)ο蟮?,OC是基于C之上的擴(kuò)展。OC的工作原理,系統(tǒng)發(fā)送消息給對(duì)象,讓對(duì)象按消息內(nèi)容工作。它用的是消息機(jī)制(Smalltallk-style)。 Mac OS X(桌面式電腦操作系統(tǒng))iOS(移動(dòng)設(shè)備操作系統(tǒng))是蘋(píng)果的兩大操作系統(tǒng) main.m m:是message的意思。
@autoreleasepool{ } //自動(dòng)釋放池 分析:@ :表示一個(gè)對(duì)象,表示字符的值。 注意:在OC中把類(lèi)聲明的指針?lè)Q為對(duì)象。 #import 《Foundation/Foundation.h》
#inport:文件包含,自動(dòng)防止重復(fù)包含。Import:是導(dǎo)入的意思。 nil :相當(dāng)C++中NULL;
NSAutoreleasePool* pool = [NSAutoreleasePool alloc]; [pool init];
?。踦ool drain];//傾倒
分析:這三句相當(dāng)自動(dòng)釋放池。[pool drain ]:給pool對(duì)象發(fā)出drain消息,中括號(hào)表示消息機(jī)制,消息由系統(tǒng)發(fā)送,pool接收。alloc:給對(duì)象分配空間,并給成員變量初始化為0,init :初始化對(duì)象,類(lèi)似于構(gòu)造函數(shù)OC創(chuàng)建一個(gè)對(duì)象。 5、gcc – framework Foundaton files –o prongame 。/program ————編譯一個(gè)源程序文件
分析:framework是框架的意思,-o :是給文件起一個(gè)別名,prongame:在這里是別名,這樣生成的可執(zhí)行文件,。/program 即可執(zhí)行
評(píng)論