0

我正在使用一个未记录的 API (Osirix),我对我在这里发布的那个有一个姐妹问题。

我在从托管对象上下文加载对象时遇到问题。

从 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而不是DicomStudys?我包括 DicomStudy.h,因此它应该在创建模型、上下文和获取请求期间看到对象。

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

提前致谢,

-斯蒂芬

4

2 回答 2

1

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

更新

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

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

并显示输出。

于 2010-05-29T18:39:19.243 回答
0

万岁,

回答我的每一个问题时,我都觉得自己像个大粪,但是哦,好吧。

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

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

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

感谢马库斯帮助我。我希望这不仅仅是一个“RTFM”问题,因为自 2009 年 11 月以来我才开始为 Apple 平台开发。我还没有开始学习 CoreData...

-斯蒂芬

于 2010-06-02T13:04:29.520 回答