4

我正在努力使我的 NSMangedObjectClass 配置文件可即时/可导出。如果我在 NSArrays 中编写关系,我会以这种方式
尝试 导出工作正常,因为 NSSet 尚未实现。
writeToFile

- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{
//Profile
NSMutableDictionary *profileDict = [[self.selectedProfile dictionaryWithValuesForKeys:[[[self.selectedProfile entity] attributesByName] allKeys]] mutableCopy];
NSMutableArray *views = [NSMutableArray array];

//Views
for (View *view in selectedProfile.views) {
    NSMutableDictionary *viewDict = [[view dictionaryWithValuesForKeys:[[[view entity] attributesByName] allKeys]] mutableCopy];
    NSMutableArray *controls = [NSMutableArray array];
         //Much more for-loops
    [viewDict setObject:controls forKey:@"controls"];
    [views addObject:viewDict];
}

[profileDict setObject:views forKey:@"views"];

if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES]) 
    NSLog(@"Saved");
else
    NSLog(@"Not saved");
[profileDict release];
}

但是如果想在另一边导入

- (Profile*) importProfileFromPath:(NSString *)path{
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context];

NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]];
[newProfile setValuesForKeysWithDictionary:profileDict];
}

我得到一个例外,这不会让我感到困惑,因为 Profile 需要一个 NSSet 而没有 NSArray。 所以我有两个问题:
[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0'

  • 一方面,我无法将 NSSet 写入文件。
  • 另一方面是我的 Profile 类需要一个 NSSet。

所以我尝试创建一个实现 writeToFile 的 NSSet 类别

@implementation NSSet(Persistence)

- (BOOL)writeToFile:(NSString*)path atomically:(BOOL)flag{
    NSMutableArray *temp = [NSMutableArray arrayWithCapacity:self.count];
    for(id element in self)
        [temp addObject:element];
    return [temp writeToFile:path atomically:flag];
}

+ (id)setWithContentsOfFile:(NSString *)aPath{
    return [NSSet setWithArray:[NSArray arrayWithContentsOfFile:aPath]];
}
@end

但是我的函数没有被调用。

还有其他方法可以编写我的 NSSet 或告诉setValuesForKeysWithDictionaryKey“views”是 NSArray 吗?

还是一种简单的方式来导入/导出 ManagedObjects?

4

2 回答 2

2

嵌套的 NSDictonarys 有问题,所以我告别了动态方式。这是我帮助其他
ViewController 调用 im/export 函数的完整解决方案

- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{
    //Call the NSManagedobject function to export
    NSDictionary *profileDict = [self.selectedProfile dictionaryForExport];

    if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES]) 
        NSLog(@"Saved");
    else
        NSLog(@"Not saved");
}

- (void) importProfileFromPath:(NSString *)path{
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context];

    //load dictonary from file
    NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]];
    //call the NSManagedObjects import function
    [newProfile importWithDictonary:profileDict context:context];

    NSError *error = nil;
    if (![context save:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

NSManagedObject 函数我有一个层次结构,所以我把它们放在我的每个 NSManagedObjects

- (void) importWithDictonary:(NSDictionary*)dict context:(NSManagedObjectContext*)context{
    self.name = [dict objectForKey:@"name"];

    //Relationship
    for (NSDictionary *view in [dict objectForKey:@"views"]) {
        View *tempView = [NSEntityDescription insertNewObjectForEntityForName:@"View" inManagedObjectContext:context];
        [tempView importWithDictonary:view context:context];
        tempView.profile = self;
        [self addViewsObject:tempView];
    }
}

- (NSDictionary*) dictionaryForExport{ 
    //propertys
    NSMutableDictionary *dict = [[[self dictionaryWithValuesForKeys:[[[self entity] attributesByName] allKeys]] mutableCopy] autorelease];
    NSURL *objectID = [[self objectID] URIRepresentation];
    [dict setObject: [objectID absoluteString] forKey:@"objectID"];
    NSMutableArray *views = [NSMutableArray array];

    //relationship
    for (View *view in self.views) {
        [views addObject:[view dictionaryForExport]];
    }
    [dict setObject:views forKey:@"views"];
    return dict;
}

不是最漂亮的解决方案,但它有效:)
我仍然要弄清楚如何避免我的 n:m 关系中的重复

谢谢

于 2011-04-12T09:16:52.367 回答
1

您可以尝试覆盖 NSManagedObject 的 setValuesForKeysWithDictionary 的默认实现吗?

查看文档,您应该只需要在子类中实现setValue:forKey:吗?

您应该能够在抛出异常之前抓住其中的 NSSet 并自己处理它吗?

[免责声明-我从未这样做过!]

于 2011-04-11T15:57:21.163 回答