我只是想知道一个对象何时由alloc
生成,并且分配了一块内存,为什么init
不使用那段内存并更改对象的地址?
NSDate *t = nil;
NSLog(@"t = %p",t); // t = 0x0
t = [NSDate alloc];
NSLog(@"t = %p",t); // t = 0x100107af0
t = [t init];
NSLog(@"t = %p",t); // t = 0x1001035a0
答案 0 :(得分:1)
两步初始化允许我们执行这些类型的操作(即,根据调用的初始化程序将类的实例替换为另一个实例)。遍布Foundation的类集群和UIKit利用此功能返回针对特定用例优化的实例。例如,UIColor
本身只是实现颜色缓存的子类的接口(所有命名的初始化器,如+blackColor
),RGB颜色空间(+colorWithRed:green:blue:alpha
),黑白颜色空格(+colorWithWhite:alpha:
),CIColor
兼容性等等。NSDate
也是如此。当你致电-init
时,Apple有手段和动机返回一个与NSDate
实现相同接口的不同对象作为优化,因为你老实说不应该关心你得到什么,只要它没有当你试图正确地发信号时发射导弹。
答案 1 :(得分:1)
从最新的iOS SDK开始,调用[NSDate alloc]
始终返回相同的内存位置。您可以使用以下代码验证此行为:
NSDate *date1, *date2;
date1 = [NSDate alloc];
NSLog(@"date1: %p", date1);
date1 = [date1 init];
NSLog(@"date1: %p", date1);
date2 = [NSDate alloc];
NSLog(@"date2: %p", date2);
date2 = [date2 init];
NSLog(@"date2: %p", date2);
我怀疑这与NSDate
是class cluster的事实有关。
如果类集群的私有子类具有不同的存储要求,则无法在alloc
内部知道要分配多少内存。解决这个问题的一种方法,看来这是Apple与NSDate
一起使用的方法,就是让init
和工厂方法处理所有内存分配,因为这些方法知道什么是私有子类实际上将被使用。
此时,所有alloc
正在为您做的是允许用户在Objective-C中保留用于对象创建的[[NSDate alloc] init]
模式。由于alloc
返回的内存位置始终被丢弃,alloc
也可能只返回一个固定的内存位置,这就是它似乎正在做的事情。