具有 privateQueueConcurrencyType 的 NSFetchedResultsController - 更改不调用委托方法
NSFetchedResultsController with privateQueueConcurrencyType - changes do not call delegate methods
在将 NSFetchedResultsControllerDelegate
设置为 privateQueueConcurrencyType
的 concurrencyType
值时,我无法调用我的 NSFetchedResultsControllerDelegate
方法。
考虑这个例子:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
coreDataManager
class 有这个:
private(set) lazy var managedObjectContext: NSManagedObjectContext = {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
如果我调用fetchedResultsController.managedObjectContext.delete(note)
然后保存,调用controller:didChangeObject:atIndexPath:forChangeType:newIndexPath
方法,我可以响应删除笔记对象。
如果我把上面的代码改成:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let managedObjectContext = NSManagedObjectContext(concurrencyType: .concurrencyType`)
managedObjectContext.persistentStoreCoordinator = self.coreDataManager.managedObjectContext.persistentStoreCoordinator
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
它专门将托管对象上下文 'usage' 从使用 self.coreDataManager.managedObjectContext
更改为应该在后台线程上工作的新版本,删除项目时永远不会调用委托方法。
- 我在
viewDidLoad
中获取一次
- 这在使用 'main' 托管对象时工作正常,
self.coreDataController.managedObjectContext
- 我或多或少地使用 https://github.com/bartjacobs/ExploringTheFetchedResultsControllerDelegateProtocol 提供的代码来演示这一点 - 正如我上面所说,请调整
fetchedResultsController
方法以使用不同的 NSManagedObjectContext
所以我的主要问题是 - 如何在使用这种类型的 NSManagedObjectContext
时调用 NSFetchedResultsControllerDelegate
方法?
fetchedResultsController
正在监视您刚刚创建的上下文,该上下文未处理更新。如果您希望更改此上下文,则必须为上下文设置 automaticallyMergesChangesFromParent = true
。
正如 John 所说,NSFetchedResultsController 仅监控关联的托管上下文,例如
lazy var fetchedResultsController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
let request = NSFetchRequest<NSFetchRequestResult>.init(entityName: "Repository")
let descriptors = [NSSortDescriptor.init(key: "name", ascending: true), NSSortDescriptor.init(key: "name", ascending: true)]
request.sortDescriptors = descriptors
let resultsController = NSFetchedResultsController.init(fetchRequest: request, managedObjectContext: CoreDataManager.shared.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
resultsController.delegate = self
return resultsController
}()
从 .privateQueueConcurrencyType 继承你的 .mainQueueConcurrencyType 就像下面的代码
lazy var managedObjectContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .mainQueueConcurrencyType)
context.parent = self.privateQueueManagedObjectContext
context.automaticallyMergesChangesFromParent = true
return context
}()
lazy var privateQueueManagedObjectContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = self.persistentStoreCoordinator
return context
}()
不要忘记在主上下文中添加 context.automaticallyMergesChangesFromParent = true 以通知 privateQue 上下文的后台操作。
我希望这会奏效
在将 NSFetchedResultsControllerDelegate
设置为 privateQueueConcurrencyType
的 concurrencyType
值时,我无法调用我的 NSFetchedResultsControllerDelegate
方法。
考虑这个例子:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
coreDataManager
class 有这个:
private(set) lazy var managedObjectContext: NSManagedObjectContext = {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
如果我调用fetchedResultsController.managedObjectContext.delete(note)
然后保存,调用controller:didChangeObject:atIndexPath:forChangeType:newIndexPath
方法,我可以响应删除笔记对象。
如果我把上面的代码改成:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let managedObjectContext = NSManagedObjectContext(concurrencyType: .concurrencyType`)
managedObjectContext.persistentStoreCoordinator = self.coreDataManager.managedObjectContext.persistentStoreCoordinator
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
它专门将托管对象上下文 'usage' 从使用 self.coreDataManager.managedObjectContext
更改为应该在后台线程上工作的新版本,删除项目时永远不会调用委托方法。
- 我在
viewDidLoad
中获取一次
- 这在使用 'main' 托管对象时工作正常,
self.coreDataController.managedObjectContext
- 我或多或少地使用 https://github.com/bartjacobs/ExploringTheFetchedResultsControllerDelegateProtocol 提供的代码来演示这一点 - 正如我上面所说,请调整
fetchedResultsController
方法以使用不同的NSManagedObjectContext
所以我的主要问题是 - 如何在使用这种类型的 NSManagedObjectContext
时调用 NSFetchedResultsControllerDelegate
方法?
fetchedResultsController
正在监视您刚刚创建的上下文,该上下文未处理更新。如果您希望更改此上下文,则必须为上下文设置 automaticallyMergesChangesFromParent = true
。
正如 John 所说,NSFetchedResultsController 仅监控关联的托管上下文,例如
lazy var fetchedResultsController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
let request = NSFetchRequest<NSFetchRequestResult>.init(entityName: "Repository")
let descriptors = [NSSortDescriptor.init(key: "name", ascending: true), NSSortDescriptor.init(key: "name", ascending: true)]
request.sortDescriptors = descriptors
let resultsController = NSFetchedResultsController.init(fetchRequest: request, managedObjectContext: CoreDataManager.shared.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
resultsController.delegate = self
return resultsController
}()
从 .privateQueueConcurrencyType 继承你的 .mainQueueConcurrencyType 就像下面的代码
lazy var managedObjectContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .mainQueueConcurrencyType)
context.parent = self.privateQueueManagedObjectContext
context.automaticallyMergesChangesFromParent = true
return context
}()
lazy var privateQueueManagedObjectContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = self.persistentStoreCoordinator
return context
}()
不要忘记在主上下文中添加 context.automaticallyMergesChangesFromParent = true 以通知 privateQue 上下文的后台操作。
我希望这会奏效