NSDate сохраняет сообщение, отправленное на освобожденный экземпляр - PullRequest
0 голосов
/ 25 марта 2011

У меня были некоторые проблемы с NSDate и сохранением его в NSUserDefaults. Похоже, что каждый второй раз, когда NSUserDefaults сохраняет мою NSDate, он не может, потому что он освобожден и показывает эту ошибку в журнале.

-[__NSDate retain]: message sent to deallocated instance 0x4c20c80

Я знаю, что NSDate по-разному распределяет и освобождает от обычных объектов, но мне было интересно, если кто-нибудь знает, используя:

- (void)saveData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
[data setObject:dateOpened forKey:@"dateOpened"];
[dData synchronize];
}

... или ...

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
dateOpened = [data objectForKey:@"dateOpened"];
}

Я выпускаю свой экземпляр NSDate и, таким образом, оставляю ему счет сохранения 0, чтобы мое приложение не могло сохранить его снова при попытке?

Я использую:

@property (retain) NSDate *dateOpened;

Любая идея была бы очень благодарна, так как я схожу с ума, пытаясь понять это. Я только учусь около 4 месяцев или около того, и я почти закончил свое первое приложение, и это главный гаечный ключ в работе!

Большое спасибо, и если вам нужно больше кода или информации о том, что я делаю, пожалуйста, дайте мне знать. : -D

Ответы [ 3 ]

2 голосов
/ 25 марта 2011

NSDate не ведет себя иначе, чем любой другой объект, в отношении управления памятью. Возможно, вы имеете в виду, что обычно используются вспомогательные операторы, такие как [NSDate date], которые возвращают объект с автоматическим освобождением (то есть объект будет удален в конце основного цикла (или всякий раз, когда пул автоматического выпуска) будет освобожден, если только не будет вызовы класса сохраняются на нем. Так как я не могу видеть весь ваш код, я могу только сделать обоснованное предположение, но я считаю, что вы вызываете release для объекта, возвращенного из [data objectForKey:], и это будет вашей ошибкой. Эта функция возвращает объект с автоматическим освобождением, и поэтому у вас нет «владения» объектом до тех пор, пока вы не вызовете для него функцию retain. Если вы не вызываете retain для него или не выделяете его явно, вы никогда не должны вызывать release для него (это относится ко всем объектам). ).

0 голосов
/ 25 марта 2011

Проблема в loadData заключается в том, что вы непосредственно присваиваете dateOpened автоматически выпущенному значению, которое станет недействительным после прохождения цикла событий.

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];

// dateOpened = [data objectForKey:@"dateOpened"];

// try:
   self.dateOpened = [data objectForKey:@"dateOpened"];

// which is basically the same as:
// [self setDateOpened:[data objectForKey:@"dateOpened"]];

// the following 2 lines could also work:
// [dateOpened release];
// dateOpened = [[data objectForKey:@"dateOpened"] retain];

}

Если у вас есть @synthesized dateOpened, вы можете представить, что следующие 2 метода были добавлены в ваш класс:

- (NSDate *)dateOpened {
  return dateOpened;
}

- (void)setDateOpened:(NSDate *)aDate {
  [aDate retain];
  [dateOpened release];
  dateOpened = aDate;
}
0 голосов
/ 25 марта 2011

У вас проблема в методе -loadData.

dateOpened = [data objectForKey:@"dateOpened"];

Это строка выше, вы получаете доступ к ивару напрямую и не проходите через свойство, которое сохраните. Таким образом, у вас есть один из двух вариантов выбора.

// First choice retain it yourself
dateOpened = [data objectForKey:@"dateOpened"];
[dateOpened retain];

Или

// Second choice have the @property do it for you
[self setDateOpened:[data objectForKey:@"dateOpened"]];

Вот почему стоит использовать подчеркивания на ваших личных иварах, чтобы вы знали, когда обращаетесь к ним напрямую. У вас будет несколько ошибок. :)

// declaring it with underscore would have caught your mistake.
NSDate *_dateOpened;
...