使用 NSKeyedUnarchiver 读取错误 class 类型
Reading wrong class type with NSKeyedUnarchiver
在我的应用程序中,我正在读取 NSMutableArray 并将其写入 NSUserDefaults。该数组包含如下所示的对象:
头文件:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@interface WorkLocationModel : NSObject
@property (nonatomic, strong) CLRegion *geoLocation;
@end
实现文件:
#import "WorkLocationModel.h"
@implementation WorkLocationModel
-(id)init {
// Init self
self = [super init];
if (self)
{
// Setup
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.geoLocation forKey:@"geoLocation"];
}
-(void)initWithCoder:(NSCoder *)coder {
self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
}
@end
这是我阅读清单的方式:
这是在我加载数组的 ViewController 中,oldArray 似乎记录了 NSKeyedUnarchiver 类型的 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。
region 是一个函数参数。
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
和 return 一个实例。你的方法应该是:
- (instancetype) initWithCoder:(NSCoder *)coder
{
self = [super init];
if(self)
self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
return self;
}
如果您的超类也实现了 initWithCoder:
,那么 super
调用将是 [super initWithCoder:coder]
(对于 encodeWithCoder:
也是如此)- NSObject
不是这样你的编码和解码都OK。
编码、解码和读取方法上的断点会迅速缩小问题范围。
HTH
在我的应用程序中,我正在读取 NSMutableArray 并将其写入 NSUserDefaults。该数组包含如下所示的对象:
头文件:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@interface WorkLocationModel : NSObject
@property (nonatomic, strong) CLRegion *geoLocation;
@end
实现文件:
#import "WorkLocationModel.h"
@implementation WorkLocationModel
-(id)init {
// Init self
self = [super init];
if (self)
{
// Setup
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.geoLocation forKey:@"geoLocation"];
}
-(void)initWithCoder:(NSCoder *)coder {
self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
}
@end
这是我阅读清单的方式:
这是在我加载数组的 ViewController 中,oldArray 似乎记录了 NSKeyedUnarchiver 类型的 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。
region 是一个函数参数。
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
和 return 一个实例。你的方法应该是:
- (instancetype) initWithCoder:(NSCoder *)coder
{
self = [super init];
if(self)
self.geoLocation = [coder decodeObjectForKey:@"geoLocation"];
return self;
}
如果您的超类也实现了 initWithCoder:
,那么 super
调用将是 [super initWithCoder:coder]
(对于 encodeWithCoder:
也是如此)- NSObject
不是这样你的编码和解码都OK。
编码、解码和读取方法上的断点会迅速缩小问题范围。
HTH