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