我一直在阅读 Objective-C 中的一些教程,当涉及到命令alloc()
以及如何使用它来初始化对象时,我感到很困惑。
本教程说要执行以下操作,但我无法弄清楚为什么需要这样做。
改变
NSDate *now = [NSDate date];
至
NSDate *now = [[NSDate alloc] init];
既然第一行工作得很好,为什么这个改变是必要的?我想我正在寻找两条线的不同之处。谢谢!
我一直在阅读 Objective-C 中的一些教程,当涉及到命令alloc()
以及如何使用它来初始化对象时,我感到很困惑。
本教程说要执行以下操作,但我无法弄清楚为什么需要这样做。
改变
NSDate *now = [NSDate date];
至
NSDate *now = [[NSDate alloc] init];
既然第一行工作得很好,为什么这个改变是必要的?我想我正在寻找两条线的不同之处。谢谢!
有一个简单的区别和一个更深的区别。
简单的答案是第一个方法在内部包含一个+alloc
/-init
对——文档告诉我们它返回一个初始化为当前时间的新日期对象。通常,在某个地方,必须有人调用+alloc
某种-init
方法。有时就是你,有时为你提供了一种方便的方法。
关于差异的更深层次的答案是+alloc
/-init
返回一个由调用者拥有的对象,然后调用者负责-release
在某些时候调用,而不以“alloc”或“new”开头的便利构造函数返回自动释放的对象你不必释放。但是,如果您使用的是 ARC,这主要是学术性的,因为编译器会为您跟踪这些细节。
分解它:
NSDate
是一类。NSDate alloc
对类方法的调用也是如此alloc
。这实际上是继承自NSObject
并为 的新实例创建足够的存储空间NSDate
,然后将其返回以用作实例。
(instance) init
是对实例方法的调用init
。在调用init
您收到的实例之前,不保证处于有效状态。调用init
或相关的初始化程序使实例有机会建立自己。
NSDate
也选择了提供类方法date
。这与[[[NSDate alloc] init] autorelease]
仅作为速记提供相同的功能。
正如其他发帖者所评论的那样,这里存在语义差异——alloc
返回一个拥有的引用。因此,调用者release
稍后对对象负责。date
返回非拥有引用。所以调用者没有责任。然而,现代的 ARC 编译器会为你处理发布的事情。因此,存在差异,但对您没有任何实际影响。
如果您的教程坚持这样date
更合适,那么它要么是在 ARC 编译器之前编写的,要么是由喜欢使用旧约定的人编写的;usingdate
传统上会传达您正在创建的东西是用于临时使用的,因此对于经验丰富的开发人员而言,可以说其中一种方式与另一种方式相比具有一些额外的价值。
使用 ARC 并不重要,因为您不再需要释放分配初始化的对象。
没有ARC,重要的区别:
[NSDate date]
使用 NSDate 上的类方法返回一个自动释放的对象。
[[NSDate alloc] init]
返回一个非自动释放的对象实例,保留计数为 1。
与非 ARC 一样,您需要自己进行内存管理,因此alloc init
是更好的选择。所以,你可以释放它,一旦不需要。
还有一点需要注意的是,自动释放的对象在自动释放池被释放时被释放。
当你 alloc init 时,你知道你的对象会一直存在,直到你释放它(或者你因为超出范围而泄漏它)。
根本没有必要进行更改。alloc+init
使用或使用便捷方法创建对象都没有关系。将它们视为传统和便利的方法。