Изучая Objective-C и читая пример кода, я замечаю, что объекты обычно создаются с помощью этого метода:
SomeObject *myObject = [[SomeObject alloc] init];
вместо того:
SomeObject *myObject = [SomeObject new];
Есть ли причина для этого, поскольку я прочитал, что они эквивалентны?
objective-c
oop
willc2
источник
источник
Ответы:
Здесь есть несколько причин: http://macresearch.org/difference-between-alloc-init-and-new
Некоторые из них:
new
не поддерживает пользовательские инициализаторы (какinitWithString
)alloc-init
более явно, чемnew
Похоже, что общее мнение заключается в том, что вы должны использовать все, что вам удобно.
источник
+newWithString:
, если вы уже реализовали-initWithString
. Не так часто, хотя. Лично я всегда использую,new
когда назначенный инициализаторinit
, просто очень короткий и сладкий.+newWithString:
. Это нарушает разделение интересов. Хотя, когда вы просто хотите использовать в-init
любом случае, нет никаких причин, чтобы просто не использовать+new
.[[NSString alloc] initWithFormat:...]
и[NSString stringWithFormat:...]
оба эквивалентны. Вы говорите, что Apple нарушила разделение интересов и не должна была реализовывать это таким образом? (Примечание: я не пытаюсь быть снисходительным; я просто хотел бы получить больше информации и знать, иногда ли плохой идеей будет следовать примеру Apple.)Очень старый вопрос, но я написал пример просто для удовольствия - может быть, вы найдете его полезным;)
В основной функции оба утверждения:
и
результат в том же выводе:
источник
[[InitAllocNewTest alloc] init]
не будет компилироваться, пока на[InitAllocNewTest new]
него не влияют. (Извинения за отсутствие разрывов строк и т. Д.)+new
эквивалентно+alloc/-init
вNSObject
реализации Apple . Маловероятно, что это когда-либо изменится, но в зависимости от вашего уровня паранойи документация Apple, по-+new
видимому, позволит изменить реализацию (и нарушить эквивалентность) в будущем. По этой причине, поскольку «явное лучше, чем неявное» и для исторической преемственности сообщество Objective-C обычно избегает+new
. Вы можете, однако, как правило , определить последние Java желающих на Objective-C их упорного использования+new
.источник
+new
что был вокруг с NeXT дней. Если что-+new
то является признаком кого-то, кто изучил предмет давно; Я вижу, что многие люди, которые пришли к новому языку или даже писали его годами, но явно после бума iOS, понятия не имеют, что это+new
значит. Во-вторых, поскольку+new
он очень старый и со времен NeXT, Apple была бы довольно безумной, чтобы изменить его таким образом, чтобы он ломал старый код, особенно учитывая, что его собственные кодовые базы, вероятно, засорены им.new
идиома происходит от Smalltalk. Он также используется в Ruby, и Objective-C и Ruby в значительной степени основаны на синтаксисе и соглашениях Smalltalk.Часто вам нужно будет передавать аргументы,
init
и поэтому вы будете использовать другой метод, например[[SomeObject alloc] initWithString: @"Foo"]
. Если вы привыкли писать это, у вас есть привычка делать это таким образом, и это[[SomeObject alloc] init]
может произойти более естественно[SomeObject new]
.источник
Один короткий ответ:
источник
Для справки, я лично использую,
[Foo new]
если я хочу, чтобы что-то в init выполнялось без использования возвращаемого значения в любом месте. Если вы не используете возврат в[[Foo alloc] init]
любом месте, то вы получите предупреждение. Более или менее я использую[Foo new]
для глазных конфет.источник
Я очень опоздал к этому, но я хочу упомянуть, что это новое на самом деле небезопасно в мире Obj-C со Swift. Swift создаст метод init по умолчанию, только если вы не создадите никакой другой инициализатор. Вызов new для класса swift с пользовательским инициализатором вызовет сбой. Если вы используете alloc / init, то компилятор будет правильно жаловаться, что init не существует.
источник
Если new сделает эту работу за вас, то он также сделает ваш код немного скромнее. Если бы вы в противном случае вызывали
[[SomeClass alloc] init]
во многих различных местах вашего кода, вы создадите «горячую точку» в реализации new, то есть во время выполнения objc, что уменьшит количество ошибок вашего кэша.В моем понимании, если вам нужно использовать пользовательский инициализатор использования
[[SomeClass alloc] initCustom]
.Если нет, используйте
[SomeClass new]
.источник
init
функцию по умолчанию и используйте ее.[[SomeClass alloc] init];
Если вам нужны параметры, все равно никогда не делайте что-то подобное[[SomeClass alloc] initWith:...];
. Наконец, если вы переопределитеinit
функцию с помощью пользовательской реализации, вы можете вызватьnew
при создании объекта, и он все равно будет вызывать пользовательскуюinit
реализацию.