1. 程式人生 > >oc--alloc和 init,為什麼init後記憶體地址變了

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