CoreData:第一次加载NSManagedObject时不访问自定义属性访问器

时间:2012-10-07 17:08:27

标签: ios core-data nsmanagedobject

结束目标:我有一个由树叶组成的对象图,连接到其他树叶。我需要遍历对象图并返回所有未枯萎的叶子,以及1)没有子叶或2)所有子叶枯萎。

情况:我有一个NSFetchedResultsController和表视图,我想显示结果。

我尝试过什么: 我开始尝试在NSFetchRequest上使用NSPredicate,但意识到我无法看到哪些可以递归地运行叶子的子叶和所有子叶等...

所以我在Leaf对象中添加了一个名为“isFarthestNonWiltedLeaf”的属性,并在Leaf上的类别中创建了一个自定义的get-accessor:

- (NSNumber*) isFarthestNonWiltedLeaf
{
    [self willAccessValueForKey:@"isFarthestNonWiltedLeaf"];
    NSNumber *returnValue = @([self.wilted boolValue] == NO && [[self allSubLeavesAreWilted] boolValue]);
    [self didAccessValueForKey:@"isFarthestNonWiltedLeaf"];

    return returnValue;
}

- (NSNumber*) allSubLeavesAreWilted
{
    for(Leaf *aLeaf in self.subLeaves)
    {
        if([aLeaf.wilted boolValue] == NO || ![[aLeaf allSubLeavesAreWilted] boolValue])
            return @NO;
    }
    return @YES;
}

然后,在NSFetchedResultsController的获取请求中,我设置了以下谓词:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"isFarthestNonWiltedLeaf == YES"]];

第一次打开应用程序并开始在不同的视图中添加叶子和子叶时,这非常有用。但是,下次打开应用程序时,第一次出现表视图时,不会访问自定义访问器方法!我必须转到每个叶子并检查/取消选中它的“枯萎”状态,然后NSFetchedResultsController刷新单个Leaf ...此时它确实调用自定义isFarthestNonWiltedLeaf访问器并且叶子正确地出现在列表中。我必须为每个叶子执行此操作,以便正确更新整个tableview。

所以我的问题是......我如何让NSFetchRequest / NSFetchedResultsController每次都使用Leaf对象的自定义get访问器?谢谢。

1 个答案:

答案 0 :(得分:0)

好吧,我将不得不回答我自己的问题......我玩了一些,我找出了问题,虽然我仍然不确定它的“原因”。

我意识到CoreData中有很多缓存,所以即使我在NSFetchedResultsController上将cacheName设置为nil,我觉得那里有一些问题。此外,似乎在不调用get访问器的情况下访问了原始属性。

换句话说,原语需要保存。所以我在计算值后立即在get accessor 中添加了以下行

[self setPrimitiveValue:returnValue forKey:@"isFarthestNonWiltedLeaf"];

起初我还添加了KVO通知代码(willChangeValueForKey和didChangeValueForKey),但这使得应用程序完全没有响应,出于某种原因......它似乎是一些周期性的引用问题。

所以最终的代码如下所示:

- (NSNumber*) isFarthestNonWiltedLeaf
{
    [self willAccessValueForKey:@"isFarthestNonWiltedLeaf"];
    NSNumber *returnValue = @([self.wilted boolValue] == NO && [[self allSubLeavesAreWilted] boolValue]);
    [self didAccessValueForKey:@"isFarthestNonWiltedLeaf"];

    [self setPrimitiveValue:returnValue forKey:@"isFarthestNonWiltedLeaf"];

    return returnValue;
}

- (NSNumber*) allSubLeavesAreWilted
{
    for(Leaf *aLeaf in self.subLeaves)
    {
        if([aLeaf.wilted boolValue] == NO || ![[aLeaf allSubLeavesAreWilted] boolValue])
            return @NO;
    }
    return @YES;
}

...与NSPredicate如下:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"isFarthestNonWiltedLeaf == YES"]];