提问



学习Objective-C并阅读示例代码,我注意到对象通常使用以下方法创建:


SomeObject *myObject = [**SomeObject alloc] init];


代替:


SomeObject *myObject = [SomeObject new];


有没有理由这样做,因为我读过他们是等同的?

最佳参考


这里有很多原因:http://macresearch.org/difference-between-alloc-init-and-new [27]


一些选定的是:



  • new不支持自定义初始值设定项(如initWithString)

  • alloc-initnew
  • 更明确


一般意见似乎是你应该使用你感到舒服的任何东西。

其它参考1


很老的问题,但我已经写了一些只是为了好玩的例子 - 也许你会觉得它很有用;)


#import "InitAllocNewTest.h"

@implementation InitAllocNewTest

+(id)alloc{
    NSLog(@"Allocating...");
    return [super alloc];
}

-(id)init{
    NSLog(@"Initializing...");
    return [super init];
}

@end


在main函数中都有两个语句:


[**InitAllocNewTest alloc] init];





[InitAllocNewTest new];


导致相同的输出:



2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating...
2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...


其它参考2


+new相当于Apple NSObject实现中的+alloc/-init。这种情况不太可能发生变化,但根据你的偏执程度,Apple的文档+new]]似乎允许将来改变实施(并打破等效性)。出于这个原因,因为明确比隐含更好而且对于历史连续性,Objective-C社区通常避免+new。但是,您可以通过他们对+new的顽固使用来发现最近的Java客户对Objective-C的看法。

其它参考3


通常,您需要将参数传递给init,因此您将使用不同的方法,例如[**SomeObject alloc] initWithString: @"Foo"]。如果你习惯于写这个,那么你养成了这样做的习惯,所以[**SomeObject alloc] init]可能更自然地[SomeObject new]

其它参考4


一个简短的回答是:



  1. 两者都是一样的。但

  2. new仅适用于基本的init初始化程序,而不会
    使用其他初始值设定项(例如initWithString:)。


其它参考5


对于附注,我个人使用[Foo new]如果我想要在init中完成某些事情而不在任何地方使用它的返回值。如果你不在任何地方使用[**Foo alloc] init]的返回,那么你会得到一个警告。或多或少,我使用[Foo new]作为眼睛糖果。

其它参考6


如果new为您完成这项工作,那么它将使您的代码也适度缩小。如果你在代码中的许多不同位置调用[**SomeClass alloc] init],你将在新的实现中创建一个热点 - 也就是说,在objc运行时 - 这将减少你的缓存未命中数。


根据我的理解,如果你需要使用自定义初始化程序[**SomeClass alloc] initCustom]


如果你没有,请使用[SomeClass new]

其它参考7


我对此很晚,但我想提一下,在带有Swift世界的Obj-C中,新的实际上是不安全的。如果您不创建任何其他初始化程序,Swift将仅创建默认的init方法。使用自定义初始化程序在swift类上调用new将导致崩溃。如果你使用alloc/init,那么编译器会正确地抱怨init不存在。