從開始學(xué)的NSString *name=[[NSString alloc] init]
起蝇闭,僅知道這句話是分配內(nèi)存空間蕴侣,一直在用泊交,從來沒考慮過它的內(nèi)部是怎么實(shí)現(xiàn)的雁歌。今天無意中看到了這一句代碼:
NSString *name = [NSString alloc];
NSLog(@"%p",name);
name = [name init];
NSLog(@"%p",name);
試著打印了一下宏浩,發(fā)現(xiàn)兩個(gè)的內(nèi)存地址不一樣:
alloc是開辟一個(gè)內(nèi)存空間,init是初始化靠瞎,為什么初始化不在原有的內(nèi)存空間上初始化比庄,而是重新開辟一個(gè)內(nèi)存空間。于是開始查資料乏盐,這時(shí)又發(fā)現(xiàn)了一個(gè)新的迷惑:
NSObject *obj = [NSObject alloc];
NSLog(@"%p",obj);
obj = [obj init];
NSLog(@"%p",obj);
打印結(jié)果:
怎么地址又變一樣了佳窑?再打印NSArray的試一試:
NSArray *person = [NSArray alloc];
NSLog(@"%p",person);
person = [person init];
NSLog(@"%p",person);
再次打印結(jié)果:
仍然是不一樣的。原因是什么呢父能?首先看看NSStrng的init方法吧:
-(id)init{
if(self = [super init]) {
// 重新賦值
//…
}
}
從代碼中可以分析神凑,self=[super init]
如果不為nil,就重新分配內(nèi)存空間何吝,這就解釋了為什么 NSString溉委,NSArray的調(diào)用alloc]init]方法后,內(nèi)存地址會(huì)不一樣岔霸,但是NSObject為什么會(huì)一樣呢薛躬,我們知道NSObject是一切類的基類,當(dāng)[[NSString alloc]init]
執(zhí)行時(shí)呆细,調(diào)用的[super init]
就是 NSObject中的init方法型宝,既然NSObject身為基類,它也就無法調(diào)用super init絮爷,所以當(dāng)NSObject執(zhí)行[[NSObject alloc]init]
時(shí)趴酣,也就沒有了init重新分配空間這一環(huán)節(jié)。
至于蘋果公司為什么初始化一個(gè)實(shí)例要分兩步坑夯,個(gè)人認(rèn)為是方便構(gòu)造后初始化不同的方法岖寞,如果用 new關(guān)鍵字,只能調(diào)用一個(gè)init柜蜈,而不能調(diào)用initWithName等方法仗谆。
知識(shí)拓展:
NSString alloc之后指巡,沒有init,那么這部分alloc后的內(nèi)存空間可不可以用隶垮?答案是顯而易見的藻雪,如果可以用,蘋果公司也就沒必要提供一個(gè)init方法狸吞,那么alloc后的指針稱為什么呢勉耀? ——懸掛指針。
如果一個(gè)地方指針既不為空蹋偏,也沒有被設(shè)置為指向一個(gè)已知的對(duì)象便斥,則這樣的指針稱為懸掛指針。在程序里面是很危險(xiǎn)的事威始。當(dāng)程序運(yùn)行使用該指針時(shí)枢纠,程序不能判斷指針的合法性,將會(huì)產(chǎn)生很嚴(yán)重的錯(cuò)誤字逗。