Нужен универсальный конструктор FetchedResultsController (Swift) - PullRequest
0 голосов
/ 16 ноября 2018

Я создал метод для построения frc:

private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) 
    -> NSFetchedResultsController<T>? {

    let fetchRequest: NSFetchRequest = T.fetchRequest()
    let sortDescriptor1 = NSSortDescriptor(key: sortKey, ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor1]

    searchContext.reset()

    var frc: NSFetchedResultsController<T>? =
        NSFetchedResultsController<T>(
        fetchRequest:            fetchRequest as! NSFetchRequest<T>,
        managedObjectContext:   searchContext,
        sectionNameKeyPath:     nil,   
        cacheName:              nil)   
    frc!.delegate = self                

    try? frc!.performFetch()
    return frc
}

Я хочу назвать что-то вроде этого из замыкания:

self.frc = self.buildFRC(entity: ObjectName, sortKey: "trackName")

но я получаю эту ошибку:

"Невозможно преобразовать значение типа 'ObjectName.Type' в ожидаемый тип аргумента 'NSManagedObject'".

Тем не менее, ObjectName - это имя класса NSManagedObject. Я попробовал себя но в итоге я просто продолжаю гоняться за ошибками по кругу.

1 Ответ

0 голосов
/ 17 ноября 2018

Объявление вашей функции не означает совсем того, что вы думаете.

private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) -> NSFetchedResultsController<T>? 

Это означает, что T должен быть подклассом NSManagedObject, и что первый аргумент должен быть экземпляром T . Когда вы называете это так

self.frc = self.buildFRC(entity: ObjectName, sortKey: "trackName")

... вы передаете подкласс в качестве первого аргумента, когда ваше объявление ожидает экземпляр.

Исправить несложно, потому что вам не нужно включать T в качестве аргумента. В общем случае, в обобщениях Swift вам не нужно передавать тип в качестве аргумента - тип исходит из того, как используется функция. Отбросьте этот аргумент и перепишите объявление как

private func buildFRC<T:NSManagedObject>(sortKey: String) -> NSFetchedResultsController<T>? {

Затем вызовите функцию с чем-то вроде

self.frc: NSFetchedResultsController<ObjectName>? = self.buildFRC(sortKey: "trackName")

Swift выяснит, что T представляет ObjectName в этом вызове, и код будет работать.

На касательной ноте ваш звонок на searchContext.reset() довольно опасен и, вероятно, не нужен. Если вы извлекаете некоторые объекты из контекста и затем вызываете эту функцию позже, reset приведет к тому, что все ранее извлеченные объекты станут недействительными. Их использование может привести к сбою вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...