alloc + init内存使用机制

时间:2013-12-22 11:52:40

标签: objective-c foundation

我只是想知道一个对象何时由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

2 个答案:

答案 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);

我怀疑这与NSDateclass cluster的事实有关。

如果类集群的私有子类具有不同的存储要求,则无法在alloc内部知道要分配多少内存。解决这个问题的一种方法,看来这是Apple与NSDate一起使用的方法,就是让init和工厂方法处理所有内存分配,因为这些方法知道什么是私有子类实际上将被使用。

此时,所有alloc正在为您做的是允许用户在Objective-C中保留用于对象创建的[[NSDate alloc] init]模式。由于alloc返回的内存位置始终被丢弃,alloc也可能只返回一个固定的内存位置,这就是它似乎正在做的事情。