学习Objective-C并阅读示例代码,我注意到对象通常是使用这种方法创建的:
SomeObject *myObject = [[SomeObject alloc] init];
而不是:
SomeObject *myObject = [SomeObject new];
有没有理由这样做,因为我读过它们是等同的?
答案 0 :(得分:284)
这里有很多原因:http://macresearch.org/difference-between-alloc-init-and-new
一些选定的是:
new
不支持自定义初始值设定项(例如initWithString
)alloc-init
比new
一般意见似乎是你应该使用你感到满意的任何东西。
答案 1 :(得分:136)
很老的问题,但我写了一些只是为了好玩的例子 - 也许你会发现它很有用;)
#import "InitAllocNewTest.h"
@implementation InitAllocNewTest
+(id)alloc{
NSLog(@"Allocating...");
return [super alloc];
}
-(id)init{
NSLog(@"Initializing...");
return [super init];
}
@end
在主要功能中两个陈述:
[[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 :(得分:52)
+new
相当于Apple +alloc/-init
实施中的NSObject
。这种情况不太可能发生变化,但根据您的偏执程度,Apple的+new
文档似乎允许在将来更改实施(并打破等效性)。出于这个原因,因为“显性优于隐式”而且对于历史连续性,Objective-C社区通常避免使用+new
。但是,您可以通过对+new
的粗暴使用来发现最近的Java客户到Objective-C。
答案 3 :(得分:8)
通常,您需要将参数传递给init
,因此您将使用其他方法,例如[[SomeObject alloc] initWithString: @"Foo"]
。如果你习惯写这篇文章,你就养成了这样做的习惯,因此[[SomeObject alloc] init]
可能更自然地[SomeObject new]
。
答案 4 :(得分:7)
一个简短的回答是:
答案 5 :(得分:3)
对于附注,我个人使用[Foo new]
如果我想在init中完成某些事情,而不在任何地方使用它的返回值。如果您未在任何地方使用[[Foo alloc] init]
的返回,那么您将收到警告。或多或少,我使用[Foo new]
作为眼睛糖果。
答案 6 :(得分:3)
我已经很晚了,但我想提一下,在带有Swift世界的Obj-C中,新的实际上是不安全的。如果您不创建任何其他初始化程序,Swift将仅创建默认的init方法。使用自定义初始化程序在swift类上调用new将导致崩溃。如果你使用alloc / init,那么编译器会正确地抱怨init不存在。
答案 7 :(得分:1)
如果new为您完成工作,那么它将使您的代码也适度缩小。如果您在代码中的许多不同位置调用[[SomeClass alloc] init]
,您将在new的实现中创建一个热点 - 即在objc运行时 - 这将减少缓存未命中的数量。
根据我的理解,如果您需要使用自定义初始化程序,请使用[[SomeClass alloc] initCustom]
。
如果不这样做,请使用[SomeClass new]
。