【问题标题】:How to create a class array in Swift如何在 Swift 中创建一个类数组
【发布时间】:2023-07-25 06:48:01
【问题描述】:

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

【问题讨论】:

  • 另一种方式是objc_getClass("NSAttributedString"),但是依赖类名作为字符串不如Sulthan的解决方案
  • 更新:在 Xcode 6 beta 3 中,这段代码似乎没有问题
  • 更新:Xcode 6 beta 6 再次出现问题
  • 更新:它似乎在 Xcode 6.1 beta 中再次修复

标签: class 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]

上一个答案

我无法在 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())

有效,但有点破解。

【讨论】:

  • 似乎在 Xcode 6 beta 3 中,不再需要这种 hack
  • 我的代码中有这个:class MyTeam: NSMutableArray {...},我想使用 swift 声明。我该怎么做?
  • 这不是一个纯粹的 swift 因为它需要 NSObject 作为超类
  • @fnc12 好吧,无论如何,这曾经是一个黑客。您不再需要它,因为该错误已被修复。
  • @Sulthan 没有 objc 有什么方法可以回答这个问题吗?
【解决方案2】:

Swift 2.0中你可以使用

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

因为&lt;ClassName&gt;.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 和类有关。

    至少可以这么说,在 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)")
            }
        }
    

    【讨论】: