NSKeyedArchiver and NSKeyedUnarchiver with NSMutableArray

前端 未结 4 1117
别那么骄傲
别那么骄傲 2021-02-04 18:05

I\'m hoping this isn\'t something to do with the fact that I\'m using a Mutable array here, but this one is baffling me so it wouldn\'t surprise me if that were the case.

<
相关标签:
4条回答
  • 2021-02-04 18:42

    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.

    0 讨论(0)
  • 2021-02-04 18:50

    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.

    0 讨论(0)
  • 2021-02-04 18:52

    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.

    0 讨论(0)
  • 2021-02-04 19:00

    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.

    0 讨论(0)
提交回复
热议问题