为啥 NSManagedObjectContext = nil 在第一次尝试获取它之后?

Posted

技术标签:

【中文标题】为啥 NSManagedObjectContext = nil 在第一次尝试获取它之后?【英文标题】:Why is NSManagedObjectContext = nil after first attempt to fetch it?为什么 NSManagedObjectContext = nil 在第一次尝试获取它之后? 【发布时间】:2011-03-12 13:37:02 【问题描述】:

我有一个NSOutlineView 和一个基于父子关系或两个核心数据 实体的自定义NSOutlineViewDataSource

我还没有找到一种直接的方法来将这些绑定到视图,所以现在我正在弄清楚如何告诉NSOutlineView 在我将新对象插入任一实体及其各自的@ 后更新987654324@.

NSOutlineView 可以在 awakeFromNib 上填充:

rootNode = [[IFParentNode alloc] initWithTitle:@"Root" children:nil];
    NSInteger clientCounter;
    clientCounter = 0;
    NSFetchRequest *clientsFetchRequest = [[NSFetchRequest alloc] init];
    NSManagedObjectContext *clientsMoc= [clientsController managedObjectContext];
    NSEntityDescription *clientsEntity = [NSEntityDescription entityForName:@"Clients" inManagedObjectContext:clientsMoc];
    [clientsFetchRequest setEntity:clientsEntity];
    //sort
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"clientCompany" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [clientsFetchRequest setSortDescriptors:sortDescriptors];
    NSError *clientsFetchError = nil;
    clientsArray = [clientsMoc executeFetchRequest:clientsFetchRequest error:&clientsFetchError];
    [clientsFetchRequest release];

    NSInteger projectCounter;
    projectCounter = 0;
    NSFetchRequest *projectsFetchRequest = [[NSFetchRequest alloc] init];
    NSManagedObjectContext *projectsMoc= [projectsController managedObjectContext];
    NSEntityDescription *projectsEntity = [NSEntityDescription entityForName:@"Projects" inManagedObjectContext:projectsMoc];
    [projectsFetchRequest setEntity:projectsEntity];
    NSError *projectsFetchError = nil;
    projectsArray = [projectsMoc executeFetchRequest:projectsFetchRequest error:&projectsFetchError];
    [projectsFetchRequest release];

    for (NSString *s in clientsArray) 
        NSManagedObject *clientMo = [clientsArray objectAtIndex:clientCounter];  // assuming that array is not empty
        id clientValue = [clientMo valueForKey:@"clientCompany"];
        //NSLog(@"Company is %@", parentValue);

        IFParentNode *tempNode = [[IFParentNode alloc] initWithTitle:[NSString stringWithFormat:@"%@", clientValue] children:nil];

        clientCounter = clientCounter + 1;
        [rootNode addChild:tempNode];
        [tempNode release];
    

    for (NSString *s in projectsArray) 
        NSInteger viewNodeIndex;
        viewNodeIndex = 0;
        NSManagedObject *projectMo = [projectsArray objectAtIndex:projectCounter];  // assuming that array is not empty
        id projectValue = [projectMo valueForKey:@"projectTitle"];
        id projectParent = [[projectMo valueForKey:@"projectParent"] valueForKey: @"clientCompany"];
        // find if theres an item with the projetParent name
        id nodeTitle = [[rootNode children] valueForKey:@"title"];
        for(NSString *companies in nodeTitle) 
            if([companies compare:projectParent] == NSOrderedSame) 
                //NSLog(@"Yeh! Company is %@ and parent is %@ and id is: %d", companies, projectParent, viewNodeIndex);
                // then assign that node to be the tempnode.
                IFParentNode *tempNode = [rootNode.children objectAtIndex:viewNodeIndex];
                IFChildNode *subTempNode = [[IFChildNode alloc] initWithTitle:[NSString stringWithFormat:@"%@", projectValue]];
                [tempNode addChild:subTempNode];
                [subTempNode release];
                [tempNode release];
             else 
                // do nothing.
            
            viewNodeIndex = viewNodeIndex + 1;
        
        projectCounter = projectCounter + 1;
    

    [outlineView expandItem:nil expandChildren:YES];

每次我向任一实体添加对象时,我都尝试调用相同的方法,认为它会再次从头开始填充NSOutlineView。相反,它只是给出一个错误:

+entityForName: could not locate an NSManagedObjectModel for entity name 'Clients'

clientsMoc 的日志显示,每次我在awakefromnib 之后调用它时它都等于 nil(它适用于此)。我在这个网站上看到了一些关于此的提及,但引用 selfNSApp 代表 对我来说还没有用。我不知道该采取什么方向?我需要返回一个不为零的 MOC。

我的 appdelegate 类是为核心数据应用程序设置的标准类。

提前致谢!

【问题讨论】:

【参考方案1】:

您报告的错误与大纲无关。这是一个核心数据错误。

要么你有错误的实体名称,要么你的 managedObject 上下文没有被初始化或正确引用。

【讨论】:

感谢 TechZen。不,实体肯定存在(正如我所说,NSOutlineView 使用我包含的代码在 awakeFromNib 上填充 ok)。只有在稍后调用该方法时,我才会收到该错误。从更多的侦探工作中,我 99% 确信它归结为 managedObjectContext,但没有一个推荐的解决方案能起到作用(例如在引用 MOC 时首先引用 self)或者是依赖 iPhone 的答案。 只是补充一点:对 managedObjectContext = nil 的检查返回为 nil 所以这肯定是我遇到的问题类型。这是我遇到问题的解决方法。我不确定上述代码的哪个方面要省略或添加以确保 MOC 在多次调用该方法时加载正常。另外,我不确定为什么它在第一次唤醒时可以正常工作,然后就停止了。 听起来您正在丢失对 managedObjectContext 的引用。我假设它是某个类的属性,例如应用程序委托。确保属性保留对象。如果您将它传递给控制器​​的属性,请确保它也保留。我注意到您不使用访问器或 self.projectsMoc 参考表单,因此这也可能是一个问题。 在这种情况下,有两个 managedObjectContexts,它们分别是 clientsControllerprojectsController 类的属性(如果我正确理解了这种情况 - 我还是新手 - 我会解决它们与例如[clientsController managedObjectContext]。检查它们是否保留对象的最佳方法是什么?我没有更改我为核心数据生成的原始xcode appDelegate,所以如果您使用 core data 启动应用程序,则 xcode 生成的标准 managedObjectContext 代码。 我有一种感觉,我可能会误解一个更大的 managedObjectContext,而不是我正在考虑的每个 NSArrayController,例如当我使用:NSManagedObjectContext *clientsMoc= [clientsController managedObjectContext];【参考方案2】:

我正在努力解决这个问题,使用谷歌上经常出现的方法来解决似乎总是与 iPhone 相关的appDelegate 中的NSManagedObjectContext。我按照以下代码制作了一个mac版本的代码:

clientsMoc = [(nameofAppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];

发现调用的clientsMoc 为nil。不过,得到我问题的实际答案。正如here 指出的那样,我不是 100% 确定,但我相信在我的情况下,这可能是因为我无意中在我的班级中创建了两个实例。我认为这可能是真的原因是因为我有时在控制台中遇到重复的错误。后来我的控制器发生了变化,所以这个问题与我的项目无关。

【讨论】:

以上是关于为啥 NSManagedObjectContext = nil 在第一次尝试获取它之后?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在这段代码中得到“未知类型名称 NSManagedObjectContext”?

为啥将 NSManagedObjectContext 保存为“干净”时会出现合并错误?

为啥 NSManagedObjectContext = nil 在第一次尝试获取它之后?

为啥在没有明确合并的情况下,更改可能会从一个 NSManagedObjectContext 填充到另一个?

NSOperation 和 ARC 中 NSManagedObjectContext 保存方法上的 EXC_BAD_ACCESS,为啥?

为啥要保留静态变量?