结束目标:我有一个由树叶组成的对象图,连接到其他树叶。我需要遍历对象图并返回所有未枯萎的叶子,以及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访问器?谢谢。
答案 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"]];