代码之家  ›  专栏  ›  技术社区  ›  Stephen Furlani

为什么对于nsfetchrequest类是错误的?

  •  0
  • Stephen Furlani  · 技术社区  · 14 年前

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

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

    从API加载时,使用上下文和模型的实例

    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请求加载(以及我自己的上下文实例和模型)

    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])));
    

    所以很明显,即使实体认为它是一个双梳序列,但事实并非如此。这只是一个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 S?我包括dicomstudy.h,所以它应该在创建模型、上下文和获取请求期间看到对象。

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

    事先谢谢,

    -史蒂芬

    2 回复  |  直到 14 年前
        1
  •  1
  •   Marcus S. Zarra    14 年前

    第一个问题,在您的模型中,您是告诉核心数据使用您的dicomstudy子类,还是将其设置为nsmanagedObject still(默认值)?

    更新

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

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

    并显示输出。

        2
  •  0
  •   Community Romance    7 年前

    Hooookay

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

    所以,答案是我所包含的框架没有编译源代码。俯身 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月以来,我只为苹果平台开发了本•德文。我还没有开始学习核心数据…

    -史蒂芬