Swift: NSArrayM controllerWillChangeContent:]: 无法识别的选择器发送到实例
Swift: NSArrayM controllerWillChangeContent:]: unrecognized selector sent to instance
在我的控制器中,我有 两个 UICollectionView
和两个不同的 NSFetchedResultsControllers
:
这就是我在 viewDidLoad:
中创建它的方式:
private func setupFetchedResultsControllers() {
let currentStudent = BWSettings.sharedSettings.currentUser as! BWCoreDataStudent
let context = NSManagedObjectContext.MR_defaultContext()
let topFetchReguest = NSFetchRequest(entityName: "BWCoreDataWishlistBook")
let positionDescriptor = NSSortDescriptor(key: "position", ascending: true)
topFetchReguest.sortDescriptors = [positionDescriptor]
topFetchedResultsController = NSFetchedResultsController(fetchRequest: topFetchReguest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
topFetchedResultsController.fetchRequest.predicate = NSPredicate(format: "student.id = %lld AND position != nil", currentStudent.id)
topFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: topCollectionView, studentWishlistContainerViewController: self)
try! topFetchedResultsController.performFetch()
let bottomFetchReguest = NSFetchRequest(entityName: "BWCoreDataWishlistBook")
let addedAtDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
bottomFetchReguest.sortDescriptors = [addedAtDescriptor]
bottomFetchedResultsController = NSFetchedResultsController(fetchRequest: bottomFetchReguest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
bottomFetchedResultsController.fetchRequest.predicate = NSPredicate(format: "student.id = %lld AND position = nil", currentStudent.id)
bottomFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: bottomCollectionView, studentWishlistContainerViewController: self)
try! bottomFetchedResultsController.performFetch()
}
这是我的自定义委托:
class BWStudentWishlistFetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate {
private var collectionView: UICollectionView!
private var collectionViewChanges = [[NSFetchedResultsChangeType: [NSIndexPath]]]()
private weak var studentWishlistContainerViewController: BWStudentWishlistContainerViewController!
init(collectionView: UICollectionView, studentWishlistContainerViewController: BWStudentWishlistContainerViewController) {
self.collectionView = collectionView
self.studentWishlistContainerViewController = studentWishlistContainerViewController
}
//MARK: - NSFetchedResultsControllerDelegate
//here are my custom default methods
}
这是一条完整的错误信息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM controllerWillChangeContent:]: unrecognized selector sent to instance 0x14ec0d930'
为什么会这样?
您的错误是您的 NSFetchedResultsController 委托正在解除分配。
而不是:
topFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: topCollectionView, studentWishlistContainerViewController: self)
您需要使用 属性 来保留对委托的引用:
var fetchDelegate = BWStudentWishlistFetchedResultsControllerDelegate(..)
...
topFetchedResultsController.delegate = self.fetchDelegate
按照您的方法,委托在 setupFetchedResultsControllers() scope
结束时被释放
在我的控制器中,我有 两个 UICollectionView
和两个不同的 NSFetchedResultsControllers
:
这就是我在 viewDidLoad:
中创建它的方式:
private func setupFetchedResultsControllers() {
let currentStudent = BWSettings.sharedSettings.currentUser as! BWCoreDataStudent
let context = NSManagedObjectContext.MR_defaultContext()
let topFetchReguest = NSFetchRequest(entityName: "BWCoreDataWishlistBook")
let positionDescriptor = NSSortDescriptor(key: "position", ascending: true)
topFetchReguest.sortDescriptors = [positionDescriptor]
topFetchedResultsController = NSFetchedResultsController(fetchRequest: topFetchReguest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
topFetchedResultsController.fetchRequest.predicate = NSPredicate(format: "student.id = %lld AND position != nil", currentStudent.id)
topFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: topCollectionView, studentWishlistContainerViewController: self)
try! topFetchedResultsController.performFetch()
let bottomFetchReguest = NSFetchRequest(entityName: "BWCoreDataWishlistBook")
let addedAtDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
bottomFetchReguest.sortDescriptors = [addedAtDescriptor]
bottomFetchedResultsController = NSFetchedResultsController(fetchRequest: bottomFetchReguest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
bottomFetchedResultsController.fetchRequest.predicate = NSPredicate(format: "student.id = %lld AND position = nil", currentStudent.id)
bottomFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: bottomCollectionView, studentWishlistContainerViewController: self)
try! bottomFetchedResultsController.performFetch()
}
这是我的自定义委托:
class BWStudentWishlistFetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate {
private var collectionView: UICollectionView!
private var collectionViewChanges = [[NSFetchedResultsChangeType: [NSIndexPath]]]()
private weak var studentWishlistContainerViewController: BWStudentWishlistContainerViewController!
init(collectionView: UICollectionView, studentWishlistContainerViewController: BWStudentWishlistContainerViewController) {
self.collectionView = collectionView
self.studentWishlistContainerViewController = studentWishlistContainerViewController
}
//MARK: - NSFetchedResultsControllerDelegate
//here are my custom default methods
}
这是一条完整的错误信息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM controllerWillChangeContent:]: unrecognized selector sent to instance 0x14ec0d930'
为什么会这样?
您的错误是您的 NSFetchedResultsController 委托正在解除分配。 而不是:
topFetchedResultsController.delegate = BWStudentWishlistFetchedResultsControllerDelegate(collectionView: topCollectionView, studentWishlistContainerViewController: self)
您需要使用 属性 来保留对委托的引用:
var fetchDelegate = BWStudentWishlistFetchedResultsControllerDelegate(..)
...
topFetchedResultsController.delegate = self.fetchDelegate
按照您的方法,委托在 setupFetchedResultsControllers() scope
结束时被释放