#ios #arrays #types #swift
#iOS #массивы #типы #swift
Вопрос:
Я хотел бы написать функцию класса, которая вернет массив типа class. Насколько я понял, я могу использовать Self
для objective-c instanceType
. Моя цель — создать extension
для 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?
Спасибо за любую помощь!
Комментарии:
1. Вы можете параметризовать функцию следующим образом:
class fund fetchObjects<Self>(...) -> Self[]?
но я не думаю, что вы можете обобщить переход от ObjC к Swift, чтобы компилятор мог гарантировать, что для каждого NSManagedObject будет соответствующий объект Swift. Хотя это было бы потрясающе, отличный вопрос.2. Просто для ясности, вы не ищете массив «подклассов», вы ищете массив экземпляров с типами, которые являются подклассом именованного суперкласса?
3. Да, это то, чего я хочу достичь, поэтому, если я вызову его в подклассе NSManagedObject, и он вернет массив экземпляров этого подкласса
4. Но если я объявляю <Self>, разве он не используется как общий, как если бы я написал класс fetchObjects<T>? Или это текущий тип класса?
Ответ №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: amp;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 { ... }
Комментарии:
1. Отлично! «.Type» — это то, что я тоже искал. На самом деле хотел сделать то же самое, что и вы в первую очередь 😉