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

Как создать массив классов в 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?

4b9b3361

Ответ 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)")
        }
    }