`NSFetchedResultsController` 在使用谓词时获取和不保存数据更改
`NSFetchedResultsController` fetched data changes with and without save when using predicate
NSFetchedResultsCotroller
在使用谓词时表现异常。以下代码打印输出:
Rows - 0
但是当我注释掉 [self saveContext]
(第一个)时,输出变为:
Rows - 1
删除谓词 (query.predicate
) 修复问题,输出始终为:
Rows - 1
我怀疑这与 NULL
在内存中与在数据库查询中的比较方式有关。知道实际发生了什么吗?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSError *error;
// Deletes persistent store coordinator behind the scene
// Create an empty entity with the optional fields attr1 (string) and attr2 (date)
Entity *e = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:[self managedObjectContext]];
[self saveContext]; // <---------------- Code to comment out
// Setup fetched results controller
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(attr1 != %@) AND (attr2 != %@)", @"", [NSDate new], nil];
NSFetchRequest *query = [[NSFetchRequest alloc] initWithEntityName:@"Entity"];
query.predicate = pred;
query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"attr1" ascending:NO]];
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:query managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
frc.delegate = self;
[frc performFetch:&error];
// Output #1
NSLog(@"Rows - %ld", frc.fetchedObjects.count);
[self saveContext];
return YES;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"Rows - %ld (Update)", controller.fetchedObjects.count);
}
编辑:
修改谓词似乎可以解决问题。仍然不知道为什么:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"((attr1 = NULL) OR (attr1 != %@)) AND ((attr2 = NULL) OR (attr2 != %@))", @"", date];
是的,我怀疑这与您的谓词有关。我认为 nil
作为替换对象的行为是不可预测的。您可以在格式字符串本身中使用 NULL
或 nil
或表示 null 的真实对象,即 [NSNull null]
。如果您尝试这样做,也许您的原始谓词也会起作用。
但还有其他事情正在发生。也许您的实体有一些默认值使谓词失败,这可以解释为什么在某些情况下保存会更改获取结果。还有就是不清楚saveContext
方法的内容是什么
另外,并不是说 [NSDate new]
产生的日期精确到 1/10000 秒,所以这部分谓词应该总是 return true
。
NSFetchedResultsCotroller
在使用谓词时表现异常。以下代码打印输出:
Rows - 0
但是当我注释掉 [self saveContext]
(第一个)时,输出变为:
Rows - 1
删除谓词 (query.predicate
) 修复问题,输出始终为:
Rows - 1
我怀疑这与 NULL
在内存中与在数据库查询中的比较方式有关。知道实际发生了什么吗?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSError *error;
// Deletes persistent store coordinator behind the scene
// Create an empty entity with the optional fields attr1 (string) and attr2 (date)
Entity *e = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:[self managedObjectContext]];
[self saveContext]; // <---------------- Code to comment out
// Setup fetched results controller
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(attr1 != %@) AND (attr2 != %@)", @"", [NSDate new], nil];
NSFetchRequest *query = [[NSFetchRequest alloc] initWithEntityName:@"Entity"];
query.predicate = pred;
query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"attr1" ascending:NO]];
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:query managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
frc.delegate = self;
[frc performFetch:&error];
// Output #1
NSLog(@"Rows - %ld", frc.fetchedObjects.count);
[self saveContext];
return YES;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"Rows - %ld (Update)", controller.fetchedObjects.count);
}
编辑:
修改谓词似乎可以解决问题。仍然不知道为什么:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"((attr1 = NULL) OR (attr1 != %@)) AND ((attr2 = NULL) OR (attr2 != %@))", @"", date];
是的,我怀疑这与您的谓词有关。我认为 nil
作为替换对象的行为是不可预测的。您可以在格式字符串本身中使用 NULL
或 nil
或表示 null 的真实对象,即 [NSNull null]
。如果您尝试这样做,也许您的原始谓词也会起作用。
但还有其他事情正在发生。也许您的实体有一些默认值使谓词失败,这可以解释为什么在某些情况下保存会更改获取结果。还有就是不清楚saveContext
方法的内容是什么
另外,并不是说 [NSDate new]
产生的日期精确到 1/10000 秒,所以这部分谓词应该总是 return true
。