【问题标题】:Why is the class wrong for NSFetchRequest?为什么 NSFetchRequest 的类错误?
【发布时间】:2010-05-28 18:54:42
【问题描述】:

我正在使用一个未记录的 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,所以我不知道它应该做什么,除了将它们加载到内存中以便@987654329 @ 可以在加载时查看它们。

完全迷路了。

救命!

为什么我的 FetchRequest 返回的具有相同实体的对象会显示为 NSManagedObjects 而不是 DicomStudys?我包含了 DicomStudy.h,因此它应该在创建模型、上下文和获取请求期间看到对象。

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

提前致谢,

-斯蒂芬

【问题讨论】:

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


    【解决方案1】:

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

    更新

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

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

    并显示输出。

    【讨论】:

    • 感谢您的回复,嗯,是吗?据我所知。 img.photobucket.com/albums/v177/maethalion/… 这些类是从框架中导入的,我认为这不会产生影响——或者至少不会产生错误或警告的差异。我不确定如何告诉模型指向这些特定的类。似乎实体“类名”设置正确,但在编译期间没有建立链接。我在 IB 中找不到任何东西,我可以告诉它使用这个特定的头文件/类。
    • 我在课堂上得到了相同的NSManagedObject
    【解决方案2】:

    万岁,

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

    所以,答案是我包含的框架没有编译源。在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.“fun-time”错误。

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

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

    -斯蒂芬

    【讨论】:

      猜你喜欢
      • 2021-10-03
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 2017-12-29
      • 2011-10-21
      • 2012-06-18
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多