Ваш код правильный.
Общее правило заключается в том, что для всех переменных, которые вы объявляете в @interface, вы должны очистить их в -dealloc
. Некоторые переменные должны быть освобождены, другие просто должны быть обнулены, в зависимости от того, как вы объявили свойство @.
В приведенном выше примере, temp , возможно, никогда не были заданы вами явно, но среда выполнения ObjC будет инициализировать значение temp равным нулю, когда экземпляр вашего класс распределяется.
Отправка -релиза на нулевой объект обычно не является проблемой, поэтому [temp release]
в порядке. Это неоперация. Когда temp имеет ненулевое значение в -dealloc,
, [temp release]
выполняет свою работу по освобождению памяти.
Если вам нужно, чтобы temp имел при создании значение, отличное от nil, вам нужно реализовать метод -init
и убедиться, что он получает какое-то значение. В то время как ваш класс является законным и функциональным без метода -init
, вы действительно должны привыкнуть включать один в каждый пользовательский класс, который вы разрабатываете.
Вам потребуется как минимум инициализатор по умолчанию: -init
. Возможно, вы также захотите разработать более подробный инициализатор, который может быть использован, чтобы дать вашему temp ivar a значение, например -initWithImage:
Вот что вы должны также включить в свой класс:
@implementation MyClass
...
- (id) init {
self = [super init];
if (self != nil) {
// The minimal default initializer.
// temp will already have a value of nil, so you don't need necessarily
// need to do anything more, unless temp needs a real value on initialization.
}
return self;
}
- (void) dealloc {
...
}
@ конец
Чтобы реализовать более подробный инициализатор, который будет известен как , обозначенный инициализатор, вам нужно что-то вроде этого:
@implementation MyClass
...
- (id) initWithImage:(UIImage *)newImage {
self = [super init];
if (self != nil) {
temp = [newImage retain];
}
return self;
}
// Implement the default initializer using your more detailed initializer.
- (id) init {
// In this default initializer, every new instance comes with a temp image!
return [self initWithImage:[UIImage imageNamed:@"foobar"]];
}
- (void) dealloc {
...
}
@end
Здесь , обозначенный initializer -initWithImage:
, является официальным инициализатором. Все остальные инициализаторы, включая -init
, реализуются с использованием -initWithImage:
.
Вы можете проявить большую осмотрительность в отношении того, следует ли реализовывать какие-либо инициализаторы помимо минимального инициализатора по умолчанию. Может быть, -init
достаточно для ваших целей. Все в порядке. Иногда более подробные инициализаторы делают использование класса более удобным. Опыт (и Сила) будет вашим гидом.
Обратите внимание, что я не использовал созданный метод доступа к свойствам ни в одном методе инициализатора. Если вас не требуют обстоятельства, вам, как правило, следует избегать использования методов доступа к свойствам в методах -init и -dealloc, главным образом из-за потенциальных проблем с болью в заднице, связанных с побочными эффектами автоматических уведомлений о кодировании значения ключа.
Методы инициализатора и dealloc играют особую роль в классе. Как дизайнер классов, вы несете ответственность за установку и очистку переменных экземпляра в этих методах. Хорошее практическое правило - оставить использование методов доступа к синтезированным свойствам для вызывающих пользователей вашего класса и реализацию других методов в классе.
Выполняя инициализацию экземпляра или освобождение, вы можете и должны касаться иваров напрямую. Они твои. Вы объявили их, так что вы можете обращаться с ними напрямую. При реализации других методов в вашем классе вы обычно должны использовать средства доступа к свойству.
Хорошая ссылка JeremyP на концептуальную документацию по объектам Cocoa. Вам обязательно следует прочитать разделы об объектах и периодически перечитывать их, поскольку вы приобретаете больше опыта в написании собственных классов. В конце концов, все это начнет обретать смысл.