Подтвердить что ты не робот

Swift: return Массив типа self

Я хотел бы написать функцию класса, которая вернет массив типа класса. Насколько я понял, я могу использовать "Self" для objective-c "instanceType". Моя цель - создать расширение для объекта NSManagedObject с помощью метода fetchObjects. Этот метод будет возвращать массив подклассов NSManagedObject. Вот пример моего псевдокода, который не компилируется:

extension NSManagedObject {

    class func fetchObjects(entity: String, context: NSManagedObjectContext, predicate: NSPredicate?, sortDescriptors: NSSortDescriptor[]?) -> Self[] {
        // can't define return type of an array with type Self
        // also var declaration does not work
        var objects : Self[]?

        return objects
    }
}

Любая идея, как я могу определить массив типа Self?

Спасибо за любую помощь!

4b9b3361

Ответ 1

Это суть того, что я использую для подобной функции, обратите внимание, что это расширение на NSManagedObjectContext, а не NSManagedObject. Возможно, что-то подобное можно было бы сделать на NSManagedObject

protocol NamedManagedObject {

    class func entityName() -> String;

}

extension NSManagedObjectContext {

    func fetchObjects<T:NSManagedObject where T:NamedManagedObject>(entity:T.Type, predicate:NSPredicate? = nil, sortDescriptors:NSSortDescriptor[]? = nil) -> T[]? {
        let request = NSFetchRequest(entityName: entity.entityName())

        request.predicate = predicate
        request.sortDescriptors = sortDescriptors

        var error:NSError? = nil
        let results = self.executeFetchRequest(request, error: &error) as? T[]

        assert(error == nil)

        return results
    }

}

extension MyObjectClass : NamedManagedObject {
    class func entityName() -> String {
        return "MyObjectClass"
    }
}

Тогда его использование выполняется так же просто, как:

let objects = managedObjectContext.fetchObjects(MyObjectClass)

Обратите внимание, что вы также можете реализовать NamedManagedObject для всех NSManagedObjects с помощью:

extension NSManagedObject : NamedManagedObject {
    class func entityName() -> String {
        return NSStringFromClass(self)
    }
}

Если вы также гарантируете, что все ваши классы явно заданы дружественными именами Objective-C:

@objc(MyManagedObject)
class MyManagedObject : NSManagedObject { ... }