Как создать массив классов в Swift
В объекте c я могу создать массив классов и использовать его в методе
NSArray *classes = @[[NSAttributedString class]];
NSArray *items = [pasteboard readObjectsForClasses:classes
options:nil];
Однако у swift нет функции класса. Возврат метатепа для класса приводит к ошибке
let aClass : AnyClass! = NSAttributedString.self
//or let aClass:AnyClass! = NSAttributedString.classForArchiver()
let pasteboard = NSPasteboard.generalPasteboard()
let classes = [aClass]
let objects = pasteboard.readObjectsForClasses(classes, options: nil)
итоговая строка приводит к "фатальной ошибке: элемент массива не может быть привязан к Objective-C"
Как создать массив классов в Swift?
Ответы
Ответ 1
По-видимому, это исправлено в Beta 3, поэтому больше не требуется обходных решений
Я нашел чистый Swift hack:
func classFromType<T: NSObject>(type: T.Type) -> AnyObject! {
return T.valueForKey("self") //ask for class indirectly...
}
var clazz: AnyObject = classFromType(NSAttributedString.self)
var classes = [clazz]
Предыдущий ответ
Мне не удалось получить экземпляр Class
любым способом в Swift. Кажется, он не может быть преобразован непосредственно из AnyClass
. Например, невозможно выполнить следующее (произойдет сбой во время выполнения)
var classes: NSMutableArray = []
classes.addObject(NSClassFromString(NSAttributedString.className()))
Итак, я зашел в Obj-C и определил простую категорию NSMutableArray
:
@implementation NSMutableArray (ClassArray)
- (void)addClassByName:(NSString *)className {
[self addObject:NSClassFromString(className)];
}
@end
Тогда
var classes: NSMutableArray = []
classes.addClassByName(NSAttributedString.className())
работает, но это немного взломан.
Ответ 2
в Swift 2.0 вы можете использовать
let urls = _pasteboard.readObjectsForClasses([NSURL.self, NSString.self], options: nil)
as <ClassName>.self
возвращает AnyClass
значение
Ответ 3
Скорее выглядит так, как будто мост массива работает над AnyObject, но ваш aClass не AnyObject, это AnyClass! - трассировка стека при ошибке говорит
Swift._arrayBridgeToObjectiveC <A, B>(Swift.Array<A>) -> Swift.Array<B> ()
а ассемблер до его остановки выглядит так, как будто они намеренно захватывают его, не будучи AnyObject.
Изменение кода на
var classAsAnyObject : AnyObject = aClass as AnyObject
//var classes = [aClass]
var classes = [classAsAnyObject]
вызывает немедленный сбой в objc_retain, как и
var array = NSArray(object:aClass)
поэтому я предполагаю, что это связано с ARC и классами.
Обработка классов как самих объектов в Свифт кажется неясным, мягко говоря.
Он не отвечает на реальный вопрос (как вы создаете массив классов), но для приложения, которое вы использовали в качестве примера, вы можете обойти его, выполнив что-то вроде:
var pasteboard = NSPasteboard.generalPasteboard()
let allObjects = pasteboard.pasteboardItems
println("allObjects=\(allObjects)")
for item : AnyObject in allObjects {
println("item=\(object_getClassName(item))")
if let pbi = item as? NSPasteboardItem {
println("item.types=\(pbi.types)")
let str = pbi.stringForType("public.utf8-plain-text")
println("item as string \(str)")
}
}