Использование alloc init вместо new - PullRequest
334 голосов
/ 06 апреля 2009

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

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

вместо:

SomeObject *myObject = [SomeObject new];

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

Ответы [ 8 ]

284 голосов
/ 06 апреля 2009

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

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

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

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

136 голосов
/ 06 марта 2013

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

#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...
52 голосов
/ 06 апреля 2009

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

8 голосов
/ 06 апреля 2009

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

7 голосов
/ 24 июля 2012

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

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

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

3 голосов
/ 04 ноября 2011

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

1 голос
/ 05 мая 2015

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

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

Если нет, используйте [SomeClass new].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...