如何在Swift中创建一个类数组

时间:2014-06-11 23:59:18

标签: class swift

在目标c中,我可以创建一个类数组并在方法中使用它

NSArray *classes = @[[NSAttributedString class]];
NSArray *items = [pasteboard readObjectsForClasses:classes
                                           options:nil];

然而,斯威夫特没有"类"功能。返回类的元组类型会导致错误

    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中创建类数组?

3 个答案:

答案 0 :(得分:13)

显然,已在Beta 3中修复此问题,因此不再需要解决方法

我找到了一个纯粹的Swift黑客:

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]

上一个回答

我无法通过Swift中的任何方式获取Class实例。它似乎无法直接从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())

有效,但它有点像黑客。

答案 1 :(得分:2)

Swift 2.0 中,您可以使用

let urls = _pasteboard.readObjectsForClasses([NSURL.self, NSString.self], options: nil)

<ClassName>.self返回AnyClass

答案 2 :(得分:1)

看起来好像数组桥在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和课程有关。

至少可以说,在Swift中将类作为对象本身的处理变得模糊不清。

它没有回答真正的问题(如何创建一个类数组),但对于您用作示例的应用程序,您可以通过执行以下操作来避开它:

    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)")
        }
    }