使用alloc init而不是new

时间:2009-04-05 23:26:06

标签: objective-c oop

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

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

而不是:

SomeObject *myObject = [SomeObject new];

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

8 个答案:

答案 0 :(得分:284)

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

一些选定的是:

  • new不支持自定义初始值设定项(例如initWithString
  • alloc-initnew
  • 更明确

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

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

一个简短的回答是:

  1. 两者都是一样的。但
  2. 'new'仅适用于基本的'init'初始化程序,而不会 使用其他初始值设定项(例如initWithString:)。

答案 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]