NSKeyedArchiver and NSKeyedUnarchiver with NSMutableArray

家住魔仙堡 提交于 2019-12-03 00:35:16

There are a few problems with your code.

Your initWithCoder: method is not fully implemented. You must call [super init] and return self. You must also copy or retain the string object, otherwise it will be autoreleased:

- (id)initWithCoder:(NSCoder *)decoder 
{
    self = [super init];
    if(self)
    {
         name    = [[decoder decodeObjectForKey: @"recordName"] copy];
         anInt   = [decoder decodeIntForKey:    @"recordInteger"];
         aBool   = [decoder decodeBoolForKey:   @"recordBool"];
    }
    return self;
}

The other problem is with this line:

database = [NSKeyedUnarchiver unarchiveObjectWithFile:myPath];

That is fine, except for two things:

  1. You're not holding a reference to the object, so it will be autoreleased.
  2. NSKeyedArchiver returns an immutable object, in this case an NSArray and not an NSMutableArray.

You need to do this:

database = [[NSKeyedUnarchiver unarchiveObjectWithFile:myPath] mutableCopy];

That will both retain the object (because it's a copy) and make the object an NSMutableArray.

It doesn't appear that you're initializing the recordObjects in -initWithCoder:

Try something like this:

-(id) initWithCoder: (NSCoder *) decoder {

    self = [super init];

    if (self){

       name    = [decoder decodeObjectForKey: @"recordName"] copy];
       anInt   = [decoder decodeIntForKey:    @"recordInteger"];
       aBool   = [decoder decodeBoolForKey:   @"recordBool"];
     }

    return self;
}

The data is there when you archive it but you're not properly unarchiving it.

Sounds like a memory management issue to me. EXC_BAD_ACCESS usually means that you're trying to access an object that has been deallocated. unarchiveObjectWithFile: returns an autoreleased object, so you have to retain it if you want to keep it around, either with an explicit retain or by assigning it to a retained property.

I was having the same issue when unarchiving a custom object

self.calTable = [[NSKeyedUnarchiver unarchiveObjectWithFile:calibrationFile] objectForKey:@"calTable"];

Based on Rob's answer I changed to

self.calTable = [[[NSKeyedUnarchiver unarchiveObjectWithFile:calibrationFile] mutableCopy] objectForKey:@"calTable"];

and it fixed all errors.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!