NSFetchedResultsController 在管理对象被修改时通知其委托删除更改,并且从不通知插入或更新
NSFetchedResultsController notifies its Delegate of delete changes when a managed object is modified, and never notifies for Insert or Update
我有一个 UITableViewController
,它是 NSFetchedResultsController
的代表。我的 NSFetchedResultsControllerDelegate
函数是根据 Apple's documentation 中的“典型用途”设置的,table 视图控制器作为获取结果控制器的委托 属性。
我还有一些视图控制器显示在 table 视图之上,可以在其中修改托管对象。这些修改是在 same 托管对象上下文中完成的。我的应用程序中只构造了一个托管对象上下文,它是全局访问的。 (我在我的对象上下文构造中放置了一些 print
语句,只是为了确保我不会不小心在别处重新构造它。)
当我修改其中一个托管对象时,委托函数 controller:didChangeObject
被调用,但是 NSFetchedResultsChangeType
总是 .Delete
。当我创建一个托管对象时,委托函数根本没有触发。
但是,当我手动调用调用 performFetch()
和 tableView.reloadData()
时,单元格恢复到正确的状态:删除的行返回,创建任何未插入的行。
结果是删除对象按预期工作(删除单元格),但更新对象会导致其单元格被删除,并且对象创建不会触发单元格插入。
我试图为这种行为创建一个简单的演示,但是当我从一个空白的应用程序重新创建这种情况时,我没有看到这种行为。所以我的应用程序中的某些东西导致了这种奇怪的行为,但我不知道是什么。有什么想法吗?
额外信息:
谓词和排序描述符的实际构造是在几个不同的 类 上完成的,但是通过 print(resultsController.fetchRequest.predicate)
和 print(resultsController.fetchRequest.sortDescriptors)
打印它们给出以下结果:
Optional(readState == "2" OR readState == "1")
Optional([(readState, ascending, compare:), (title, ascending, compare:)])
我在我的 controller:didChangeObject:
方法中放置了一条打印语句,我可以看到它仅在使用 type.rawValue = 2
(即 .Delete
)时被调用,并且仅当我修改对象时,而不是在我创建它们时。
这与 NSFetchedResultsController
处理其 NSPredicate
的方式不一致。
如果 NSFetchedResultsController
是用一个提取请求构造的,该请求具有一个谓词,该谓词在整数和字符串之间进行比较,如下所示:
let predicate = NSPredicate(format: "integerAttribute == %@", String(1))
这将导致谓词字符串为:
integerAttribute == "1"
在这种情况下,初始提取工作正常:在提取结果控制器上调用函数 performFetch()
returns integerAttribute
等于 [=17= 的所有对象](其中 integerAttribute
属于 Int32
类型)。
但是,NSFetchedResultsControllerDelegate
的通知无法正常工作。托管对象的修改会导致委托收到 NSFetchedResultsChangeType.Delete
更改通知。托管对象的创建根本不调用委托。
为了消除所有这些怪异现象,请按如下方式修复谓词格式字符串:
let predicate = NSPredicate(format: "integerAttribute == %d", 1)
我有一个 UITableViewController
,它是 NSFetchedResultsController
的代表。我的 NSFetchedResultsControllerDelegate
函数是根据 Apple's documentation 中的“典型用途”设置的,table 视图控制器作为获取结果控制器的委托 属性。
我还有一些视图控制器显示在 table 视图之上,可以在其中修改托管对象。这些修改是在 same 托管对象上下文中完成的。我的应用程序中只构造了一个托管对象上下文,它是全局访问的。 (我在我的对象上下文构造中放置了一些 print
语句,只是为了确保我不会不小心在别处重新构造它。)
当我修改其中一个托管对象时,委托函数 controller:didChangeObject
被调用,但是 NSFetchedResultsChangeType
总是 .Delete
。当我创建一个托管对象时,委托函数根本没有触发。
但是,当我手动调用调用 performFetch()
和 tableView.reloadData()
时,单元格恢复到正确的状态:删除的行返回,创建任何未插入的行。
结果是删除对象按预期工作(删除单元格),但更新对象会导致其单元格被删除,并且对象创建不会触发单元格插入。
我试图为这种行为创建一个简单的演示,但是当我从一个空白的应用程序重新创建这种情况时,我没有看到这种行为。所以我的应用程序中的某些东西导致了这种奇怪的行为,但我不知道是什么。有什么想法吗?
额外信息:
谓词和排序描述符的实际构造是在几个不同的 类 上完成的,但是通过 print(resultsController.fetchRequest.predicate)
和 print(resultsController.fetchRequest.sortDescriptors)
打印它们给出以下结果:
Optional(readState == "2" OR readState == "1")
Optional([(readState, ascending, compare:), (title, ascending, compare:)])
我在我的 controller:didChangeObject:
方法中放置了一条打印语句,我可以看到它仅在使用 type.rawValue = 2
(即 .Delete
)时被调用,并且仅当我修改对象时,而不是在我创建它们时。
这与 NSFetchedResultsController
处理其 NSPredicate
的方式不一致。
如果 NSFetchedResultsController
是用一个提取请求构造的,该请求具有一个谓词,该谓词在整数和字符串之间进行比较,如下所示:
let predicate = NSPredicate(format: "integerAttribute == %@", String(1))
这将导致谓词字符串为:
integerAttribute == "1"
在这种情况下,初始提取工作正常:在提取结果控制器上调用函数 performFetch()
returns integerAttribute
等于 [=17= 的所有对象](其中 integerAttribute
属于 Int32
类型)。
但是,NSFetchedResultsControllerDelegate
的通知无法正常工作。托管对象的修改会导致委托收到 NSFetchedResultsChangeType.Delete
更改通知。托管对象的创建根本不调用委托。
为了消除所有这些怪异现象,请按如下方式修复谓词格式字符串:
let predicate = NSPredicate(format: "integerAttribute == %d", 1)