Ios 使用NSKeyedUnarchiver读取错误的类类型

Ios 使用NSKeyedUnarchiver读取错误的类类型,ios,objective-c,nsobject,nskeyedarchiver,nskeyedunarchiver,Ios,Objective C,Nsobject,Nskeyedarchiver,Nskeyedunarchiver,在我的应用程序中,我正在读写一个NSMutableArray到NSUserDefaults。此数组包含如下所示的对象: 头文件: #import <Foundation/Foundation.h> #import <CoreLocation/CoreLocation.h> @interface WorkLocationModel : NSObject @property (nonatomic, strong) CLRegion *geoLocation; @end

在我的应用程序中,我正在读写一个NSMutableArray到NSUserDefaults。此数组包含如下所示的对象:

头文件:

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@interface WorkLocationModel : NSObject

@property (nonatomic, strong) CLRegion *geoLocation;

@end
以下是我阅读清单的方式:

这是在我加载阵列的ViewController中,oldArray似乎记录了NSKeyedUnachiver类型的1项(正确数量),而它应该是WorkLocationModel对象:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *workLocationsData = [defaults objectForKey:@"workLocations"];
if (workLocationsData != nil)
{
    NSArray *oldArray = [NSKeyedUnarchiver unarchiveObjectWithData:workLocationsData];

    if (oldArray != nil)
    {
        _workLocations = [[NSMutableArray alloc] initWithArray:oldArray];
        NSLog(@"Not nil, count: %lu", (unsigned long)_workLocations.count);
    } else
    {
        _workLocations = [[NSMutableArray alloc] init];
    }
} else
{
    _workLocations = [[NSMutableArray alloc] init];
}
以下是我将WorkLocationModel对象添加到阵列的方式:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Create a sample work location
WorkLocationModel *newModel = [[WorkLocationModel alloc] init];
newModel.geoLocation = currentRegion;
[_workLocations addObject:newModel];

// Save the new objects
[defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:_workLocations] forKey:@"workLocations"];

// Synchronize the defaults
[defaults synchronize];
错误发生在这里的if语句上(深入到我的ViewController),在这里我比较两个clregion

区域是一个函数参数

    for (WorkLocationModel *currentWorkLocationModel in _workLocations)
{
    if ([region isEqual:currentWorkLocationModel.geoLocation])
    {
        // Found a match
    }
}
我已经阅读了代码,但我不明白为什么会发生这种情况,异常消息:

-[NSKeyedUnarchiver geoLocation]: unrecognized selector sent to instance 0x174108430
2015-01-12 18:23:20.085 myApp[1322:224462] *** Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '-[NSKeyedUnarchiver geoLocation]:
unrecognized selector sent to instance

有人能帮我吗?我迷路了initWithCoder:方法与任何其他init方法一样-它必须调用
super
并返回一个实例。你的方法应该是:

- (instancetype) initWithCoder:(NSCoder *)coder
{
   self = [super init];
   if(self)
      self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
   return self;
}
如果您的超类也实现了
initWithCoder:
super
调用将是
[super initWithCoder:coder]
(对于
encodeWithCoder:
),则不实现
NSObject
,因此您的编码和解码都是正常的

在编码、解码和读取方法上设置一个断点会很快缩小问题范围


HTH

删除一个问题,然后第二天作为一个新问题重新发布,这是一种非常糟糕的形式。@rmaddy可能看起来像是我迫不及待地这么做了,但我的目的是让它更清楚。很抱歉,本可以编辑它。请您再解释一点,我不太明白您对代码示例下面文本的理解。谢谢你的解决方案!如果类
A
继承自
NSObject
并实现
initWithCoder:
/
encodeWithCoder:
,类
B
继承自
A
,则类的
B
的编码/解码方法必须调用
A
的编码/解码方法,以处理
A
的状态,以及编码/解码
B
的状态。
- (instancetype) initWithCoder:(NSCoder *)coder
{
   self = [super init];
   if(self)
      self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
   return self;
}