核心数据布尔键值更改未反映在fetch中

时间:2013-08-07 15:19:11

标签: ios objective-c core-data

给定一个删除了布尔属性的NSManagedObject子类(由于两种方法都不起作用,因此以下面的代码以两种不同的方式进行演示):

[代码清单1]

@interface MyManagedObject : NSManagedObject

@property (nonatomic, retain) NSNumber *deleted;
// Or @property (nonatomic) BOOL deleted;

@end

创建并插入Core Data,如下所示:

[代码清单2]

metadata.deleted = [NSNumber numberWithBool:NO];
// metadata.deleted = NO;

并获取

[代码清单3]

// setup entity description
NSEntityDescription* entityDescription = [self entityDescription];

// setup the sorter
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
NSSortDescriptor* sortDescriptorSection = [[NSSortDescriptor alloc] initWithKey:@"myManagedObject.category.title" ascending:YES];

// Build request
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setSortDescriptors:[NSArray arrayWithObjects:sortDescriptorSection, sortDescriptor, nil]];
[request setPredicate:[NSPredicate predicateWithFormat:@"deleted == %@", [NSNumber numberWithBool:NO]]];

// Fetch request
NSArray* items = [[self managedObjectContext] executeFetchRequest:request error:nil];

按预期返回items数组中的一个项目。问题是删除时被修改:

[代码清单4]

MyManagedObject* myManagedObject; // Assume initialized
myManagedObject.deleted = [NSNumber numberWithBool:YES];
// myManagedObject.deleted = YES;

// Printing description of myManagedObject in debugger shows deleted = 0 at this point

[myManagedObject.managedObjectContext save:nil];

// Printing description of myManagedObject in debugger still shows deleted = 0 at this point

BOOL testValue = myManagedObject.deleted;
if (testValue) {
    NSLog(@"value updated"); // This line is executed
}

即使在观察数据库的NSFetchResultsController触发更新后,重新执行代码清单3仍会在items数组中生成一个项目。如果应用程序终止并重新启动,则重新执行代码清单3将不会在NSArray项中产生任何项目。

3 个答案:

答案 0 :(得分:2)

调用核心数据属性“已删除”与isDeleted的{​​{1}}属性冲突。

比较Core Data NSPredicate "deleted == NO" does not work as expected是否存在类似问题和一些实验。

顺便说一下。调用属性“已更新”也会导致问题,请比较Cannot use a predicate that compares dates in Magical Record

答案 1 :(得分:0)

您不应该将deleted用作NSManagedObject子类的属性名。

此外,删除的是NSNumber,而不是BOOL。所以,当你使用时:

BOOL testValue = myManagedObject.deleted;
if (testValue) {
    NSLog(@"value updated"); // This line is executed
}

您正在测试myManagedObject的deleted属性是否为nil。如果有值(即使[NSNumber numberWithBool:YES]),testValue也为真。

在一个不相关的说明中,我还建议在调用NSManagedObjectContext的save方法时捕获并记录错误。

答案 2 :(得分:0)

请注意,这不仅仅是已删除和isDeleted的问题。我写了一个数据库,其中我有一个“关系”属性,这是一个int16(选择几种关系类型),但后来我还有一个“isRelationship”布尔值,它查看了这个属性和其他几个以确定内容是否是关于个人或关系。 valueForKey:@“relationship”将返回isRelationship的bool - 这意味着它也影响了NSPredicate。以下谓词:

<button disabled>a</button>

将无法过滤掉朋友或家人关系,因为他们都是从isRelationship而不是实际关系值返回1。

当涉及“布尔”时,请注意愚蠢的“聪明”系统行为。

(我通过将“ - (bool)isRelationship”方法更改为“ - (bool)isRelational”来修复此问题。)