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