oc--alloc和 init,為什麼init後記憶體地址變了
從開始學的NSString *name=[[NSString alloc]init] 起,老師教這句話是分配記憶體空間,一直在用,從來沒考慮過它的內部是怎麼實現的.今天無意中看到了這一句程式碼
NSString *name=[NSString alloc];
NSLog(@"%p",name);
name=[name init];
NSLog(@"%p",name);
試著列印了一下,發現兩個的記憶體地址不一樣:
2014-07-07 13:19:51.724 LessonMRC2[1222:303] 0x100203850
2014-07-07 13:19:51.726 LessonMRC2[1222:303] 0x7fff73ada7b8
alloc是開闢一個記憶體空間,init是初始化,為什麼初始化不在原有的記憶體空間上初始化,而是重新開闢一個記憶體空間
於是開始查資料,這時又發現了一個新的迷惑:
NSObject *obj=[NSObject alloc];
NSLog(@"%p",obj);
obj = [obj init];
NSLog(@"%p",obj);
列印之後:
2014-07-07 13:23:10.663 LessonMRC2[1232:303] 0x100103730
2014-07-07 13:23:10.665 LessonMRC2[1232:303] 0x100103730
怎麼地址又變一樣了
在列印NAArray的試一試
NSArray *name=[NSArray alloc];
NSLog(@"%p",name);
name=[name init];
NSLog(@"%p",name);
列印:
2014-07-07 13:26:15.154 LessonMRC2[1244:303] 0x100103740
2014-07-07 13:26:15.156 LessonMRC2[1244:303] 0x100102f50
仍然是不一樣的.
原因是什麼哪?
首先看看NSStrng的init方法吧:
-(id)init
{
if(self=[super init]) // 重新賦值了
{
。。。。
}
}
從程式碼中可以分析, self=[super init]如果不為nil,就重新分配記憶體空間,這就解釋了為什麼 NSString,NSArray的呼叫alloc]init]方法後,記憶體地址會不一樣,
但是NSObject為什麼會一樣哪,我們知道NSObject是一切類的基類,當[[NSString alloc]init]執行時, 呼叫的[super init]就是 NSObject中的init方法,既然NSObject身為基類,他也就無法呼叫super init, 所以 當NSObject執行 [[NSObject alloc]init]時,也就沒有了init重新分配空間這一環節
至於蘋果公司為什麼初始化一個例項要分兩步,我個人認為是方便構造後初始化不同的方法,如果用 new關鍵字,只能呼叫一個init,而不能呼叫initwithname等方法.
知識拓展:
NSString alloc之後,沒有init,那麼這部分alloc後的記憶體空間可不可以用?答案是顯而易見的,如果可以用,蘋果公司也就沒必要提供一個init方法,那麼alloc後的指標稱為什麼哪? 懸掛指標.
如果一個地方指標既不為空,也沒有被設定為指向一個已知的物件,則這樣的指標稱為懸掛指標。在程式裡面是很危險的事.
當程式執行使用該指標時,程式不能判斷指標的合法性,將會產生很嚴重的錯誤。
轉自:http://www.daxueit.com/article/4371.html