为什么NSFetchRequest的类错了?

时间:2010-05-28 18:54:42

标签: c++ objective-c core-data nsmanagedobject

我正在使用未记录的API(Osirix),我有一个姐妹问题to the one I posted here.

我无法从托管对象上下文加载对象。

使用API​​加载,使用_context和_model

的实例
2010-05-28 14:05:13.588 OsiriX[44012:a0f] Entity: Study
2010-05-28 14:05:13.589 OsiriX[44012:a0f] EntityClassName: DicomStudy
2010-05-28 14:05:13.589 OsiriX[44012:a0f] ClassName: DicomStudy

从Fetch Request(以及我自己的_context和_model实例)加载

2010-05-28 14:19:09.956 rcOsirix[44431:7a03] Entity: Study
2010-05-28 14:19:09.957 rcOsirix[44431:7a03] EntityClassName: DicomStudy
2010-05-28 14:19:09.958 rcOsirix[44431:7a03] ClassName: NSManagedObject

输出由:

NSLog(@"Entity: %@",[[item entity] name]);
NSLog(@"EntityClassName: %@", [[item entity] managedObjectClassName]);
NSLog(@"ClassName: %s", class_getName(object_getClass([item class])));

很明显,即使实体认为它是DicomSeries - 它也不是。它只是一个NSManagedObject。 DicomSeries有一些“硬编码”的KVC内容,我在另一个问题上遇到了问题。

我在这个线程中追求一个不同的推理线 - 加载对象。

以下是他们的代码:

- (NSManagedObjectModel *)managedObjectModel
{
    if (managedObjectModel) return managedObjectModel;

    NSMutableSet *allBundles = [[NSMutableSet alloc] init];
    [allBundles addObject: [NSBundle mainBundle]];
    [allBundles addObjectsFromArray: [NSBundle allFrameworks]];

    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"/OsiriXDB_DataModel.mom"]]];
    [allBundles release];

    return managedObjectModel;
}

- (NSManagedObjectContext *) managedObjectContextLoadIfNecessary:(BOOL) loadIfNecessary
{
    NSError *error = nil;
    NSString *localizedDescription;
    NSFileManager *fileManager;

    if( currentDatabasePath == nil)
        return nil;

    if (managedObjectContext)
        return managedObjectContext;

    if( loadIfNecessary == NO) return nil;

    fileManager = [NSFileManager defaultManager];

    [persistentStoreCoordinator release];

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: self.managedObjectModel];

    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator: persistentStoreCoordinator];

    NSURL *url = [NSURL fileURLWithPath: currentDatabasePath];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error])
    {
        NSLog(@"********** managedObjectContextLoadIfNecessary FAILED: %@", error);
        localizedDescription = [error localizedDescription];
        error = [NSError errorWithDomain:@"OsiriXDomain" code:0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:error, NSUnderlyingErrorKey, [NSString stringWithFormat:@"Store Configuration Failure: %@", ((localizedDescription != nil) ? localizedDescription : @"Unknown Error")], NSLocalizedDescriptionKey, nil]];
    }

    [[managedObjectContext undoManager] setLevelsOfUndo: 1];
    [[managedObjectContext undoManager] disableUndoRegistration];

    // This line is very important, if there is NO database.sql file
    [self saveDatabase: currentDatabasePath];

    return managedObjectContext;
}

这是我的代码:

NSManagedObjectModel* DataModule::managedObjectModel()
{
if (_managedObjectModel) return _managedObjectModel;

    NSMutableSet *allBundles = [[NSMutableSet alloc] init];
    [allBundles addObject: [NSBundle mainBundle]];
    [allBundles addObjectsFromArray: [NSBundle allFrameworks]];

_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"/OsiriXDB_DataModel.mom"]]];

    [allBundles release];

return [_managedObjectModel retain];
}

...
        NSError *error = nil;
        [_storeCoordinator release];

        _storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel()];

        _context = [[NSManagedObjectContext alloc] init];
        [_context setPersistentStoreCoordinator: _storeCoordinator];

        NSURL *url = [NSURL fileURLWithPath: [[NSString alloc] initWithCString:_DBPath.c_str()]];

        if (url == nil) { [pool release]; _loadLock = false; return nil; }

        if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error])
        {
            NSLog(@"********** managedObjectContextLoadIfNecessary FAILED: %@", error);
            NSString *localizedDescription = [error localizedDescription];
            error = [NSError errorWithDomain:@"OsiriXDomain" code:0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:error, NSUnderlyingErrorKey, [NSString stringWithFormat:@"Store Configuration Failure: %@", ((localizedDescription != nil) ? localizedDescription : @"Unknown Error")], NSLocalizedDescriptionKey, nil]];

            //Exit Failure
            [pool release]; _loadLock = false; return nil;
        }

        [[_context undoManager] setLevelsOfUndo: 1];
        [[_context undoManager] disableUndoRegistration];
...

我包含了所有相同的框架......但_allBundles甚至没有用于创建managedObjectModel所以我不知道它应该做什么,除了将它们加载到内存中所以mom可以在加载时查看它们。

完全迷失了。

帮助!

为什么我的FetchRequest返回的具有相同实体的对象是NSManagedObjects而不是DicomStudy?我包括DicomStudy.h所以它应该在创建模型,上下文和获取请求时看到对象。

[request setEntity: [[managedObjectModel() entitiesByName] objectForKey:@"Study"]];

提前致谢,

-Stephen

2 个答案:

答案 0 :(得分:1)

第一个问题,在你的模型中,你是告诉Core Data使用你的DicomStudy子类还是设置为NSManagedObject(默认)?

更新

好的,接下来,将第三行记录更改为以下内容:

NSLog(@"ClassName: %@", [item class]);

显示输出。

答案 1 :(得分:0)

Hooookay,

我感觉自己像是一个巨大的粪便来回答我的每一个问题,但是哦。

所以,答案是我所包含的框架没有编译源代码。 BenT over Apple Dev Forums提到需要编译源代码...所以我查看了我导入的框架,看来它只是复制头文件,而不是编译任何东西。

这已经完成(我认为,因为我没有得到该框架的开发者的回复),因为该框架旨在用作主要软件插件的一部分。由于插件体系结构加载了所有已编译的类,因此只有框架中的标题可以防止objc[1378]: Class BLAH is implemented in both X and Y. One of the two will be used. Which one is undefined.“有趣的”错误。

所以,看起来我必须要包含源代码或者从源代码创建一个新的框架。

感谢Marcus帮助我。我希望这不仅仅是一个“RTFM”问题,因为自2009年11月以来我只是为苹果平台做爱。我还没有学习CoreData ......

-Stephen