Использование alloc init вместо нового

Изучая Objective-C и считывая пример кода, я замечаю, что объекты обычно создаются с помощью этого метода:

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

вместо:

SomeObject *myObject = [SomeObject new];

Есть ли причина для этого, поскольку я прочитал, что они эквивалентны?

Ответ 1

Здесь есть несколько причин: http://macresearch.org/difference-between-alloc-init-and-new

Некоторые из них:

  • new не поддерживает пользовательские инициализаторы (например, initWithString)
  • alloc-init более явный, чем new

Общее мнение кажется, что вы должны использовать то, с чем вам удобно.

Ответ 2

Очень старый вопрос, но я написал несколько примеров просто для удовольствия - может быть, вы найдете это полезным;)

#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...

Ответ 3

+new эквивалентен +alloc/-init в реализации Apple NSObject. Маловероятно, что это когда-либо изменится, но в зависимости от вашего уровня паранойи, документация Apple для +new, по-видимому, позволяет изменить реализацию (и нарушить эквивалентность) в будущем. По этой причине, поскольку "явный лучше, чем неявный" и для исторической непрерывности, сообщество Objective-C обычно избегает +new. Тем не менее, вы можете заметить недавние Java-адресатели Objective-C своим упрямым использованием +new.

Ответ 4

Часто вам нужно передать аргументы в init, и поэтому вы будете использовать другой метод, например [[SomeObject alloc] initWithString: @"Foo"]. Если вы привыкли писать это, вы привыкли делать это таким образом, и поэтому [[SomeObject alloc] init] может быть более естественным, что [SomeObject new].

Ответ 5

Один короткий ответ:

  • Оба одинаковы. Но
  • 'new' работает только с базовым инициализатором init и не будет работать с другими инициализаторами (например, initWithString:).

Ответ 6

Для стороннего примечания я лично использую [Foo new], если я хочу, чтобы что-то в init выполнялось без использования его возвращаемого значения в любом месте. Если вы не используете возврат [[Foo alloc] init] в любом месте, вы получите предупреждение. Более или менее, я использую [Foo new] для глазных конфет.

Ответ 7

Я очень опаздываю на это, но хочу упомянуть, что это новое на самом деле небезопасно в Obj-C со стремительным миром. Swift будет создавать только метод init по умолчанию, если вы не создадите другой инициализатор. Вызов нового класса Quick с пользовательским инициализатором приведет к сбою. Если вы используете alloc/init, тогда компилятор будет правильно жаловаться, что init не существует.

Ответ 8

Если новое задание для вас, то это сделает ваш код еще скромнее. Если бы вы в противном случае назовете [[SomeClass alloc] init] во многих разных местах вашего кода, вы создадите Hot Spot в новой реализации, то есть в среде выполнения objc, что уменьшит количество промахов в кэше.

В моем понимании, если вам нужно использовать пользовательский инициализатор, используйте [[SomeClass alloc] initCustom].

Если вы этого не сделаете, используйте [SomeClass new].