IOS: NSUserDefault для массива UIImage - PullRequest
0 голосов
/ 26 января 2012

Я хочу сохранить массив UIImage, и я делаю это:

//in didFinishLaunchingWithOption

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
if (data == NULL)  arrayImage = [[NSMutableArray alloc] init];
else {arrayImage = [[NSMutableArray alloc] init]; arrayImage = [NSKeyedUnarchiver unarchiveObjectWithData:data];}
NSLog(@"arrayImage:%@", arrayImage);

//and in applicationDidEnterBackground

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arrayImage];
[defaults setObject:data forKey:@"theKey"];
NSLog(@"arrayImage:%@", arrayImage);

при запуске приложения в didFinishLaunchingWithOption в nslog Я вижу все объекты в моем массиве, но когда я его использую, у меня происходит сбойкоторые говорят «[__NSArrayM count]: сообщение отправлено на освобожденный экземпляр» почему?

Ответы [ 2 ]

1 голос
/ 26 января 2012

Я не совсем уверен, но я думаю, что

+ (id) unarchiveObjectWithData: (NSData *) данные

дает вам автоматически выпущенный объект, так что вы можете сохранить его. И я думаю, что это даст вам неизменяемый объект, поэтому, когда вы попытаетесь добавить или удалить объекты из него, вы получите ошибку (я не уверен в этом, но я думаю, что когда-то был в этой ситуации). .)

Я бы переписал какую-то часть вашего кода:

...
if (data == nil)
{
    arrayImage = [[NSMutableArray alloc] init];
} else
{
    //arrayImage = [[NSMutableArray alloc] init]; //why to allocate and initialize if you are goind to unarchive it?
    //arrayImage = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain]; //note the retain here
    NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data]; //the unarchive won't mantain mutability (I guess).
    arrayImage = [NSMutableArray arrayWithArray:arr]; //create a mutable copy
}
...
1 голос
/ 26 января 2012

Я полагаю, вы не используете ARC. Проблема в:

if (data == NULL)
  arrayImage = [[NSMutableArray alloc] init];
else {
  arrayImage = [[NSMutableArray alloc] init];
  // HERE
  arrayImage = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

На HERE вы заменяете значение в arrayImage новым экземпляром для ключевого разархиватора. Значение, которое вы init только что ранее потеряли (фактически утекло). Значение из unarchiver - объект с автоматическим выпуском, поэтому он будет освобожден при сливе пула. Это до вызова applicationDidEnterBackground.

Правильное решение - сохранить значение от unarchiver. Viz:

if (data == nil)
  arrayImage = [[NSMutableArray alloc] init];
else
  arrayImage = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain];
...