從開始學的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後的指針稱為什麼哪? 懸掛指針.
如果一個地方指針既不為空,也沒有被設置為指向一個已知的對象,則這樣的指針稱為懸掛指針。在程序裡面是很危險的事.
當程序運行使用該指針時,程序不能判斷指針的合法性,將會產生很嚴重的錯誤。