编码和解码自定义对象
Posted
技术标签:
【中文标题】编码和解码自定义对象【英文标题】:Encoding and decoding custom objects 【发布时间】:2015-01-18 12:05:55 【问题描述】:我在编码和保存包含 MKMapItem 的自定义对象列表到 NSUserDefaults 时遇到问题。
首先,我从用于 tableView 的 MKMapItems 数组中获取选定的 MKMapItem,并将其存储在我的 sharedManager 实例中。 (sharedManager 中的所有值将在稍后用于创建自定义对象)。
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// Get the tapped MKMapItem
MKMapItem *selectedMapItem = self.searchResults[indexPath.row];
// Create a sharedManager instance
MyManager *sharedManager = [MyManager sharedManager];
// Set the workRegion and workLocation in sharedManager
NSLog(@"selectedMapItem: %@", [selectedMapItem name]);
sharedManager.workLocation = selectedMapItem;
// Post a notification to alert the PreviewMapViewController
[[NSNotificationCenter defaultCenter] postNotificationName:@"showAnnotations" object:self.searchResults];
[[NSNotificationCenter defaultCenter] postNotificationName:@"zoomToAnnotation" object:selectedMapItem];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showMap" object:nil];
这是我用来从 sharedManager 获取 MKMapItem 并将其放入我创建的自定义对象的代码:
MyManager *sharedManager = [MyManager sharedManager];
newModel.workLocation = sharedManager.workLocation;
我的自定义对象将 workLocation 存储在其头文件中,其属性如下:
@property (nonatomic, strong) MKMapItem *workLocation;
这是我对 workLocation 对象进行编码和解码的实现文件:
@implementation WorkLocationModel
-(id)init
// Init self
self = [super init];
if (self)
// Setup
return self;
- (void)encodeWithCoder:(NSCoder *)coder
[coder encodeObject:self.workLocation forKey:@"workLocation"];
-(instancetype)initWithCoder:(NSCoder *)coder
self = [super init];
if (self)
self.workLocation = [coder decodeObjectForKey:@"workLocation"];
return self;
@end
我的断点设置为捕获 encodeObject 行上的所有异常中断。
当我将此自定义对象添加到 NSMutableArray 然后使用以下方法保存该数组时发生错误:
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:_myObjects] forKey:@"myObjects"];
例外: -[MKMapItem encodeWithCoder:]:无法识别的选择器发送到实例 0x7f9f14acf400
谁能帮我解决这个问题?
更新:
NSData *workLocationData = [NSKeyedArchiver archivedDataWithRootObject:sharedManager.workLocation];
【问题讨论】:
【参考方案1】:MKMapItem
不符合 NSCoding
或 SSecureCoding
。
您需要对各个项目进行编码并在解码时重新创建MKMapItem
。
【讨论】:
我可以将其转换为 NSData 吗?如果可以 - 如何? 因为它不符合 NSCoding,我如何编码每个单独的项目?NSCoding
基本上就是这样做的。
所以我使用 NSKeyedArchiver 对 MKMapItem 进行编码,然后也使用 NSKeyedArchiver 对整个自定义对象进行编码?
NSArchiver
,NSCoder
的具体子类,所以首先你需要实现NSCoder
,这意味着encodeWithCoder
和initWithCoder
。然后你将有一个NSData
对象。通常这样做是为了将NSData
保存到文件中。以上是关于编码和解码自定义对象的主要内容,如果未能解决你的问题,请参考以下文章