Использование 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]
.