我希望CoreData的通用fetchedResultController支持多个模型

时间:2018-11-21 21:45:21

标签: ios swift generics core-data nsfetchedresultscontroller

我已经简化了我的问题,使问题更容易解决,所以希望我发布的代码足够。

我的目标是使用一个可以支持CoreData的多个模型的类,这样我就可以避免为每个类重新创建相同的内容。

class FRC<T> where T: NSManagedObject {
    let context: NSManagedObjectContext

    fileprivate lazy var fetchedResultscontroller: NSFetchedResultsController<T> = { [weak self] in
        guard let this = self else {
            fatalError("lazy property has been called after object has been descructed")
        }
        guard let request = T.fetchRequest() as? NSFetchRequest<T> else {
            fatalError("Can't set up NSFetchRequest")
        }
        request.sortDescriptors = [NSSortDescriptor(key: "key", ascending: true)]
        return NSFetchedResultsController<T>(fetchRequest: request,
                                             managedObjectContext: this.context,
                                             sectionNameKeyPath: nil,
                                             cacheName: nil)
        }()

    init(context: NSManagedObjectContext) {
        self.context = context
    }
}

enum ModelType {
    case modelA
    case modelB
}

class GenericDataModel: NSObject {
    let container: NSPersistentContainer
    // STUPID!!!
    var frcA: FRC<ModelA>?
    var frcB: FRC<ModelB>?

    init(modelType: ModelType) {
        container = NSPersistentContainer(name: "MyContainer")
        container.loadPersistentStores { _, error in /* Handle */ }
        // Below here is ugly!
        switch modelType {
        case .modelA:
            frcA = FRC<ModelA>(context: container.viewContext)
        case .modelB:
            frcB = FRC<ModelB>(context: container.viewContext)
        }
    }
}

extension GenericDataModel: NSFetchedResultsControllerDelegate {
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
                    didChange anObject: Any,
                    at indexPath: IndexPath?,
                    for type: NSFetchedResultsChangeType,
                    newIndexPath: IndexPath?) {
        // Handle
    }
}

看来,我能做的最好的事情就是在GenericDataModel类中为不同的模型类创建多个变量,这对于很多变量来说无法很好地扩展。

但是,尝试为FRC类创建单个局部变量一直失败,而且我不明白为什么。

我是泛型新手,所以可能我只是在做一些愚蠢的事情。

1 个答案:

答案 0 :(得分:0)

这不是一个坏主意。我已经做到了: https://github.com/jon513/FetchedResultsControllerNeverCrash/blob/master/coreDataNeverCrash/FetchedResultsControllerManager.swift

这实现了一种使核心数据在同时进行删除和更新时永不崩溃的方法(请参阅App crashes after updating CoreData model that is being displayed in a UITableView),并使api变得更容易。

要使用它,请创建一个具有fetchRequest,上下文和委托的FetchedResultsControllerManager。

委托实现很简单:

class Foo {
    async someLongMethod(){
        ... Do stuff
    }
}

class Bar {
    async someOtherMethodThatWillWait(){
        //Will the following work?
        await Foo.prototype.someLongMethod.call(this);
        ... Do stuff but only after someLongMethod has completed

    }
}

由于泛型的原因,我无法使委托的返回正确的类,但是我从来不需要对其他任何东西进行测试,因此它永远不会困扰我。如果您可以将其与泛型一起使用,我希望收到请求请求。