Я надеялся составить список некоторых различий в терминах между java и цель c, чтобы уменьшить мою путаницу. Это облегчает объяснение моих трудностей, когда я знаю, что называется.
То, что я ищу, - это аналогичные сравнения или исправления с теми, которые я перечислил. Не только ограничивается элементами на языке, но и понятиями...
Ответ 3
Философский ответ о alloc/init.
init не является конструктором. Понятно, что "конструкция" не существует в Objective-C. В Java (и других языках с конструкторами) вызов конструктора вернет новое создание объекта, который готов к работе. Точного эквивалента этому в Objective-C нет. (Можно утверждать, что методы класса удобства, такие как + array, + arrayWithObjects и т.д. Являются технически конструкторами, поскольку они переносят как распределение, так и инициализацию, но я бы сказал, что они все еще не являются конструкторами в том же смысле, что и Java-конструкторы.)
Вместо этого у нас есть концепция выделения и инициализации, два разных шага, которые при выполнении вместе действуют так, как если бы они были "конструктором". Метод класса + alloc просто запрашивает у блока необходимый размер памяти. IIRC, для этого используется функция calloc(). Не гарантируется, что любое обнуление будет иметь место во время выполнения функции alloc. Это означает, что нам нужно выполнить инициализацию самостоятельно, что мы делаем, сразу же вызвав метод -init.
ОДНАКО, -init (и все производные) - не что иное, как обычные методы экземпляра. Вы можете сообщать о них, когда захотите, чтобы "reset" экземпляр объекта в исходное состояние инициализировалось (хотя для этого необходимо учитывать некоторые изменения в управлении памятью). Это также означает, что вы можете сделать что-то смешное:
NSUInteger count = [[[NSArray alloc] autorelease] count];
Я не могу придумать, почему вы хотите это сделать, но дело в том, что вы можете. Далее следует подчеркнуть, что init не является конструктором. В приведенном выше примере объект существует к моменту возврата метода + alloc. Однако он не может быть правильно инициализирован, а это означает, что целое число без знака может не равняться нулю. Это может быть, но было бы неверно полагаться на это поведение (если, конечно, не оговорено иначе).
Одним из преимуществ разрушения конструкции в распределении и инициализации является то, что мы можем иметь большую степень контроля над тем, что происходит при инициализации. Например, в Java у вас может быть только один конструктор на подпись метода. Другими словами, если у вас есть конструктор, который принимает один аргумент "Object", то это единственный конструктор, который может. Вы не можете создать другой конструктор, который также принимает один аргумент Object.
В Objective-C типы параметров не являются частью сигнатуры метода (известный как "селектор" ), поэтому я могу создать инициализатор следующим образом:
- (id) initWithAnObject:(id)anObject;
Однако я также могу создать еще один инициализатор:
- (id) initWithADifferentObject:(id)anObject;
Я могу установить для них совершенно разные инициализации объекта, на который они вызывается. Это невероятно полезно!
Другим действительно полезным аспектом построения расщепления в распределении и инициализации является то, что вы можете связывать инициализаторы. AFAIK, вы не можете вызывать конструкторы из конструкторов в таких языках, как Java (ну, вы можете, но это не имеет такого же эффекта). Однако в Objective-C вы можете сделать что-то вроде этого:
- (id) initWithCapacity:(NSUInteger)initialCapacity {
if (self = [super init]) {
[self setInitialCapacity:initialCapacity];
}
return self;
}
- (id) init {
return [self initWithCapacity:0];
}
Теперь, когда вы выделяете/инициализируете объект, настроенный таким образом, он будет "перенаправлять" и использовать инициализатор initWithCapacity, даже если вы вызвали init. (Так работает метод init NSArray). Это означает, что вы можете использовать условные инициализаторы. Например, если ваш -init-метод отправляет один инициализатор при определенных условиях, но использует другой в разных условиях.
Таким образом, модель Objective-C "выделять и инициализировать" намного мощнее, чем идея построения. Вы, как программист, имеете гораздо больший контроль над начальной фазой установки вашего объекта. Это действительно освобождающий сдвиг.
ps - init не является конструктором!;)