alloc 与 init 的初步探索
我们创建对象的时候一般都是NSObject * objc = [[NSObject alloc] init];
,可以给对象进行各种属性赋值或者调用方法等等,那么alloc
和init
都有什么不同呢?
就先创建一个类LGPerson
,我们分别看看alloc
和init
的地址 :
如下代码:
LGPerson *p11 = [LGPerson alloc];
LGPerson *p12 = [p11 init];
LGPerson *p13 = [p11 init];
LGPerson *p21 = [LGPerson alloc];
LGPerson *p22 = [p21 init];
LGPerson *p23 = [p21 init];
LGPerson *p31 = [LGPerson alloc];
LGPerson *p32 = [p31 init];
LGPerson *p33 = [p31 init];
NSLog(@"%@-%p-%p",p11,p11,&p11);
NSLog(@"%@-%p-%p",p12,p12,&p12);
NSLog(@"%@-%p-%p",p13,p13,&p13);
NSLog(@"%@-%p-%p",p21,p21,&p21);
NSLog(@"%@-%p-%p",p22,p22,&p22);
NSLog(@"%@-%p-%p",p23,p23,&p23);
NSLog(@"%@-%p-%p",p31,p31,&p31);
NSLog(@"%@-%p-%p",p32,p32,&p32);
NSLog(@"%@-%p-%p",p33,p33,&p33);
上打印结果:
<LGPerson: 0x600002e9c650>-0x600002e9c650-0x16f1ebf38
<LGPerson: 0x600002e9c650>-0x600002e9c650-0x16f1ebf30
<LGPerson: 0x600002e9c650>-0x600002e9c650-0x16f1ebf28
<LGPerson: 0x600002e9c660>-0x600002e9c660-0x16f1ebf20
<LGPerson: 0x600002e9c660>-0x600002e9c660-0x16f1ebf18
<LGPerson: 0x600002e9c660>-0x600002e9c660-0x16f1ebf10
<LGPerson: 0x600002e9c670>-0x600002e9c670-0x16f1ebf08
<LGPerson: 0x600002e9c670>-0x600002e9c670-0x16f1ebf00
<LGPerson: 0x600002e9c670>-0x600002e9c670-0x16f1ebef8
从打印的内容可以看到:
p11
p12
p13
这三个对象的地址
是一样的,alloc
具有开辟一块内存功能,而init
没有开辟内存的功能。 但是它们的指针的地址
却是不一样的,p11
p12
p13
都有了一个指针地址
,这3个指针地址
同时指向这个内存空间
。同样:p22
p21
p23
以及p31
p32
p33
也是一样的。
比较一下:p11
p12
p13
的指针地址
:0x16f1ebf38
, 0x16f1ebf30
, 0x16f1ebf28
,可以看到3个对象的指针地址
为连续开辟,这些指针地址
都是在栈
里面,是连续的指针地址
,是高地址
到低地址
。p22
p21
p23
以及p31
p32
p33
也是一样的。
比较一下:p11
p21
p31
的对象内存地址
:0x600002e9c650
, 0x600002e9c660
, 0x600002e9c670
,可以看到3个对象的内存地址
为连续开辟,这些对象的内存地址
在堆
里面,是连续的内存地址
,是低地址
到高地址
。
说的有些晕,那用图表示就明了一些,如图所示:
那么其他的类会不会也是这样子的呢?
那我们就以系统的类NSObject
来试试:
NSObject *n11 = [NSObject alloc];
NSObject *n12 = [n11 init];
NSObject *n13 = [n11 init];
NSObject *n21 = [NSObject alloc];
NSObject *n22 = [n21 init];
NSObject *n23 = [n21 init];
NSObject *n31 = [NSObject alloc];
NSObject *n32 = [n31 init];
NSObject *n33 = [n31 init];
NSLog(@"%@-%p-%p",n11,n11,&n11);
NSLog(@"%@-%p-%p",n12,n12,&n12);
NSLog(@"%@-%p-%p",n13,n13,&n13);
NSLog(@"%@-%p-%p",n21,n21,&n21);
NSLog(@"%@-%p-%p",n22,n22,&n22);
NSLog(@"%@-%p-%p",n23,n23,&n23);
NSLog(@"%@-%p-%p",n31,n31,&n31);
NSLog(@"%@-%p-%p",n32,n32,&n32);
NSLog(@"%@-%p-%p",n33,n33,&n33);
打印结果如下:
<NSObject: 0x600002e98870>-0x600002e98870-0x16f1ebef0
<NSObject: 0x600002e98870>-0x600002e98870-0x16f1ebee8
<NSObject: 0x600002e98870>-0x600002e98870-0x16f1ebee0
<NSObject: 0x600002e98880>-0x600002e98880-0x16f1ebed8
<NSObject: 0x600002e98880>-0x600002e98880-0x16f1ebed0
<NSObject: 0x600002e98880>-0x600002e98880-0x16f1ebec8
<NSObject: 0x600002e98890>-0x600002e98890-0x16f1ebec0
<NSObject: 0x600002e98890>-0x600002e98890-0x16f1ebeb8
<NSObject: 0x600002e98890>-0x600002e98890-0x16f1ebeb0
可以看出都是同样的。
总结:
alloc
具有开辟一块内存功能,而init
没有开辟内存的功能。
栈
区开辟的内存
是高地址
到低地址
,堆
区则是低地址
到高地址
。