1

我有一个NSPersistentDocument给定的核心数据模型等。

我有一个由该文档创建的文件,假设它是preload.xml。它“包含”几个NSManagedObjects。

我想将这些对象加载到我所有的新文档中,这样当我创建一个新文档时,新文档会自动“拥有”preload.xml 中的“活动”对象。到目前为止,这是我所做的:

  • 我复制preload.xml到我的项目中。

  • initWithType:error:方法(创建新文档时调用的方法)中,有以下代码:

    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                                pathForResource:@"preload"
                                                ofType:@"xml"]];
    NSError* err = nil;
    
    [self readFromURL:preloadURL
               ofType:@"xml"
                error:&err] ;
    

这不起作用,因为当我之后尝试将文档保存到时,假设myNewDoc.xml这个文件是空的,但我所有的新数据都保存到preload.xml.

我想知道是否需要创建一个新的storeorcontextstoreCoordinator其他东西。我从来没有处理过这样的对象,因为我一直使用NSPersistentDocument.

4

1 回答 1

1

获取保存的对象:

    NSPersistentStoreCoordinator * newPersStoreCoord ;
    newPersStoreCoord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:theDoc.managedObjectModel] ;

    NSString * path = [[NSBundle mainBundle] pathForResource:@"preload"
                                                      ofType:@"xml"];
    NSURL *preloadURL = [NSURL fileURLWithPath:path];



    [newPersStoreCoord addPersistentStoreWithType:NSBinaryStoreType
                                    configuration:nil
                                              URL:preloadURL
                                          options:nil
                                            error:NULL] ;

    NSManagedObjectContext * auxMOC = [[NSManagedObjectContext alloc] init] ;
    [auxMOC setPersistentStoreCoordinator:newPersStoreCoord] ;

将它们复制到您的“活” MOC

  [self loadPreloadedDataFromTheMOC:auxMOC
                             toTheMOC:theDoc.managedObjectContext
                            forTheDoc:theDoc] ;

在克隆技术的帮助下

- (NSManagedObject *)cloneInContext:(NSManagedObjectContext *)context
                    withCopiedCache:(NSMutableDictionary *)alreadyCopied
                     exludeEntities:(NSArray *)namesOfEntitiesToExclude
                  excludeAttributes:(NSArray *)namesOfAttributesToExclude
{
    NSString *entityName = [[self entity] name];

    if ([namesOfEntitiesToExclude containsObject:entityName])
    {
        return nil;
    }

    NSManagedObject *cloned = [alreadyCopied objectForKey:[self objectID]];
    if (cloned != nil)
    {
        return cloned;
    }


    //create new object in data store
    cloned = [NSEntityDescription insertNewObjectForEntityForName:entityName
                                           inManagedObjectContext:context];
    [alreadyCopied setObject:cloned
                      forKey:[self objectID]];

    //loop through all attributes and assign then to the clone
    NSDictionary *attributes = [[NSEntityDescription entityForName:entityName
                                            inManagedObjectContext:context] attributesByName];


    for (NSString *attr in attributes)
    {
        if (![namesOfAttributesToExclude containsObject:attr])
        {
            [cloned setValue:[self valueForKey:attr] forKey:attr];
        }
    }

    //Loop through all relationships, and clone them.
    NSDictionary *relationships = [[NSEntityDescription entityForName:entityName
                                               inManagedObjectContext:context] relationshipsByName];



    for (NSString *relName in [relationships allKeys])
    {
        NSRelationshipDescription *rel = [relationships objectForKey:relName];

        NSString *keyName = rel.name;

        if ([rel isToMany])
        {
            id sourceSet ;
            id clonedSet ;

            /*
             On gère selon que la relation est ordonnée ou non
             */
            if (![rel isOrdered])
            {
                //get a set of all objects in the relationship
                sourceSet = [self mutableSetValueForKey:keyName];
                clonedSet = [cloned mutableSetValueForKey:keyName];
            }
            else
            {
                sourceSet = [self mutableOrderedSetValueForKey:keyName];
                clonedSet = [cloned mutableOrderedSetValueForKey:keyName];
            }

            NSEnumerator *e = [sourceSet objectEnumerator];
            NSManagedObject *relatedObject;

            while (relatedObject = [e nextObject])
            {
                //Clone it, and add clone to set
                NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context
                                                                     withCopiedCache:alreadyCopied
                                                                      exludeEntities:namesOfEntitiesToExclude
                                                                   excludeAttributes:namesOfAttributesToExclude];
                if (clonedRelatedObject)
                {
                    [clonedSet addObject:clonedRelatedObject];
                }
            }
        }
        else
        {
            NSManagedObject *relatedObject = [self valueForKey:keyName];
            if (relatedObject != nil)
            {
                NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context
                                                                     withCopiedCache:alreadyCopied
                                                                      exludeEntities:namesOfEntitiesToExclude
                                                                   excludeAttributes:namesOfAttributesToExclude];
                if (clonedRelatedObject)
                {
                    [cloned setValue:clonedRelatedObject forKey:keyName];
                }
            }
        }
    }

    return cloned;
}
于 2014-01-23T14:22:00.050 回答