我需要跨设备传输单个对象。现在我正在将 NSManagedObject 转换为字典,将其存档并作为 NSData 发送。收到后我将其解档。但我真的很想通过归档和取消归档来传输 NSManagedObject 本身,而不是创建中间数据对象。
@interface Test : NSManagedObject<NSCoding>
@property (nonatomic, retain) NSString * title;
@end
@implementation Test
@dynamic title;
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.title = [coder decodeObjectForKey:@"title"]; //<CRASH
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.title forKey:@"title"];
}
@end
NSData *archivedObjects = [NSKeyedArchiver archivedDataWithRootObject:testObj];
NSData *objectsData = archivedObjects;
if ([objectsData length] > 0) {
NSArray *objects = [NSKeyedUnarchiver unarchiveObjectWithData:objectsData];
}
上面代码的问题是。它崩溃于self.title
in initWithCoder
说无法识别的选择器发送到实例。
- Why is
title
不被识别为选择器。
- 在创建对象之前,应该以某种方式取消归档使用 nil 托管对象上下文
initWithCoder
?
- 我需要覆盖吗
copyWithZone
?
下面的这段代码应该可以解决问题。主要区别在于调用super initWithEntity:insertIntoManagedObjectContext:
- (id)initWithCoder:(NSCoder *)aDecoder {
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:<YourContext>];
self = [super initWithEntity:entity insertIntoManagedObjectContext:nil];
NSArray * attributeNameArray = [[NSArray alloc] initWithArray:self.entity.attributesByName.allKeys];
for (NSString * attributeName in attributeNameArray) {
[self setValue:[aDecoder decodeObjectForKey:attributeName] forKey:attributeName];
}
return self;
}
上面的代码片段将仅处理属性,不处理关系。处理人际关系如NSManagedObjectID
using NSCoding
太可怕了。如果您确实需要引入关系,请考虑在解码时引入额外的属性来匹配两个(或多个)实体。
如何获得<YourContext>
(基于 Sam Soffes 的现已不可用的帖子,代码取自https://gist.github.com/soffes/317794#file-ssmanagementobject-m)
+ (NSManagedObjectContext *)mainContext {
AppDelegate *appDelegate = [AppDelegate sharedAppDelegate];
return [appDelegate managedObjectContext];
}
注:更换<YourContext>
在第一个片段中mainContext
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)