Objective-C中的alloc和init問題


從開始學的NSString *name=[[NSString alloc] init] 起,僅僅這句話是分配內存空間,一直在用,從來沒考慮過它的內部是怎么實現的。今天無意中看到了這一句代碼:

NSString *name = [NSString alloc];
NSLog(@"%p",name);
name = [name init];
NSLog(@"%p",name);

試着打印了一下,發現兩個的內存地址不一樣:

 

alloc是開辟一個內存空間,init是初始化,為什么初始化不在原有的內存空間上初始化,而是重新開辟一個內存空間。於是開始查資料,這時又發現了一個新的迷惑:

NSObject *obj = [NSObject alloc];
NSLog(@"%p",obj);
obj = [obj init];
NSLog(@"%p",obj);

打印結果:

怎么地址又變一樣了?再打印NSArray的試一試:

NSArray *person = [NSArray alloc];
NSLog(@"%p",person);
person = [person init];
NSLog(@"%p",person);

再次打印結果:

仍然是不一樣的。原因是什么呢?首先看看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后的指針稱為什么呢? 懸掛指針。 

如果一個地方指針既不為空,也沒有被設置為指向一個已知的對象,則這樣的指針稱為懸掛指針。在程序里面是很危險的事。當程序運行使用該指針時,程序不能判斷指針的合法性,將會產生很嚴重的錯誤。

 

【掃描關注更多精彩內容】

微信公眾號:xiaoniu


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM