gpt4 book ai didi

ios - NSFetchedResultsController 由 NSManagedObject 的 refreshObject 触发。为什么?

转载 作者:搜寻专家 更新时间:2023-10-30 20:16:34 25 4
gpt4 key购买 nike

我有一个 NSFetchedResultsController 从 CoreData 存储中获取数据。当 frc 初始化时,我调用 performFetch 并检查 frc.fetchedObjects 中获取的对象的数量,结果应该是 0。

在我调用的代码的另一个地方:

[obj.managedObjectContext refreshObject:obj mergeChanges:NO]

虽然我什至不确定是否需要它,但它的副作用是导致 frc 获取一些最初未获取的对象,并且考虑到所使用的查询,无论如何都不应该获取这些对象。这些对象与调用 refreshObject:mergeChanges: 时使用的对象完全相同。

为什么会这样?

编辑:

此查询不会发生:

query.predicate = [NSPredicate predicateWithFormat:@"(cartEntry != NULL) AND (urlWeb = NULL)", version, dateUrlExpire];

frc = [[NSFetchedResultsController alloc] initWithFetchRequest:query managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
frc.delegate = self;
[frc performFetch:&error];

但是当我将查询更改为这个版本时,它发生了(所有记录的 urlWebVersionurlWebDate 都是 NULL):

query.predicate = [NSPredicate predicateWithFormat:@"(cartEntry != NULL) AND ((urlWeb = NULL) OR (urlWebVersion != %@) OR (urlWebDate > %@))", version, dateUrlExpire];

* 编辑 #2 *

这是一个最小的代码示例,显示了奇怪的行为(执行期间没有错误):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

NSError *error;

// Create an empty entity with the optional fields attr1 (string) and attr2 (date)
Entity *e = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:[self managedObjectContext]];

// Save entity
[_managedObjectContext save:&error];

// 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:_managedObjectContext sectionNameKeyPath:nil cacheName:nil];

frc.delegate = self;

// Load data
[frc performFetch:&error];

// Output #1
NSLog(@"%ld", frc.fetchedObjects.count);

[_managedObjectContext refreshObject:e mergeChanges:NO];

return YES;
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSLog(@"%ld", controller.fetchedObjects.count);
}

输出:

2015-01-22 22:53:44.293 CoreDataBug[10740:1445186] 0
2015-01-22 22:53:44.317 CoreDataBug[10740:1445186] 1

最佳答案

你的问题是 NSPredicate 很难将 != 匹配到 nil 值。例如,在您的 Edit 2 行中:

[NSPredicate predicateWithFormat:@"(attr1 != %@) AND (attr2 != %@)",
@"", [NSDate new], nil];

如您所知,在获取请求后返回零。 (那里有一个额外的零,但它不会影响任何东西)。但将其更改为:

NSPredicate *pred = [NSPredicate predicateWithFormat:
@"((attr1 != %@) || (attr1 == nil)) AND ((attr2 != %@) || (attr2 == nil))",
@"", [NSDate new]];

确实返回实体,即使在逻辑上它们是相同的。

这是记录在案的行为,尽管如此违反直觉的东西很难遵循,请参阅 Predicate Programming Guide 中的“使用空值”小节.

不清楚为什么刷新对象会导致谓词突然匹配;这可能是一个错误。然而,鉴于上述文档,!= 不应该用于可能为 nil 的值(除非检查 != nil)没有成对的 || (x = 无)。不仅有点烦人而且违反直觉。

关于ios - NSFetchedResultsController 由 NSManagedObject 的 refreshObject 触发。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28093833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com