@property сохранить - iPhone - PullRequest
       26

@property сохранить - iPhone

3 голосов
/ 14 января 2011

Я новичок в программировании iPhone. У меня есть следующие сомнения, которые мешают мне идти вперед. Пожалуйста, рассмотрите следующий код:

---------.h------
@interface myClass: UIViewController
{
    UIImage *temp;
}

@property (nonatomic, retain) UIImage *temp;

 ---------.m------
 @interface myClass
 @synthesize temp;

 -(void) dealloc
 {
   [temp release];
   [super dealloc];
 } 
  1. Выше приведен единственный программный код. Вот и все ... ничего больше. Нужно ли объявлять [temp release] в методе dealloc, хотя я вообще не использую метод доступа к свойствам в моей программе. Что если я не объявлю [временный выпуск] в dealloc. Приведет ли это к утечке памяти при выпуске чего-то, что я не сохранил, так как не вызываю метод доступа к свойству.

  2. Кроме того, когда я печатаю счетчик сохранения для температуры, почему он показывает 0, даже если он сохраняется в @ property.

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 14 января 2011
  1. Если значение (экземпляр) myClass.temp никогда не было назначено, то утечки не будет.Но вы должны освободить его в свой dealloc. Свойство

  2. @ является только объявлением, что экземпляр myClass будет иметь это свойство.Вам нужно присвоить ему значение до того, как это значение будет сохранено.

    myClass *instance = [[myClass alloc] init];
    
    // instance will now retain the value passed in
    // and is therefore responsible for releasing it
    instance.temp = [UIImage imageNamed:@"whatever"];
    
    // if instance is not retained anywhere else,
    // its dealloc will be called
    [instance release];
    

В sidenote вы должны дать своим классам имена, которые начинаются с заглавной буквы, то есть MyClass.Не требуется, но проясняет ситуацию.

Вы также можете использовать self.temp = nil; в своем dealloc Сорт не предполагается, но он работает лучше и выглядит чище.Это немного сомнительная тема ...

0 голосов
/ 20 января 2011

Ваш код правильный.

Общее правило заключается в том, что для всех переменных, которые вы объявляете в @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. Вам обязательно следует прочитать разделы об объектах и ​​периодически перечитывать их, поскольку вы приобретаете больше опыта в написании собственных классов. В конце концов, все это начнет обретать смысл.

0 голосов
/ 14 января 2011

То, что вы делаете, правильно. Прокрутите до раздела "dealloc" этого Apple Doc: Объявленные свойства

Однако вскоре эти свойства будут очищены автоматически, когда вы их синтезируете (в следующем обновлении Какао) - это, как говорится, соглашение, которому я лично стал следовать, так что мой код работает в будущем - установка 1005 * в dealloc вместо отправки сообщения о выпуске (прочитайте опубликованный мной документ Apple, он объясняет это). Метод доступа, созданный во время выполнения, сначала освобождает объект, поэтому для меня и многих других разработчиков это лучший / более безопасный способ очистки объявленных свойств в нашем dealloc.

...