通过引用传递 class 类型

Passing a class type by reference

所以我希望我的基础 tableView 能够集中拖放操作。这些 tableView 中的每一个都有一个独特的数组控制器作为其数据源,每个项目 class 都符合粘贴板读写协议。

但我卡在了它的设置上

override func mouseDragged(with event: NSEvent) {
    let arrayController = self.dataSource as! NSArrayController
    let itemClass = arrayController.objectClass
    let objects = arrayController.arrangedObjects as! [itemClass]
    let indexSet = self.selectedRowIndexes
    var items = [NSDraggingItem]()

    for index in indexSet {
        let item = NSDraggingItem.init(pasteboardWriter: objects[index])
        items.append(item)
    }
    self.beginDraggingSession(with: items, event: event, source: self)
}

当我收到错误消息时?

简短回答:这不是 Swift 的工作方式,将(as?as!)转换为适当的编译时间类型——在这种情况下,来自 NSDraggingItem.init(pasteboardWriter: objects[index]) 中的 objects 的使用,可能是 [NSPasteBoardWriting]

更长的答案:

您可能刚刚犯了一个简单的错误,我们有时都会犯这样的错误,简短的回答就足够了。但是,如果您想知道 为什么 您的代码不被接受,也许这会有所帮助,希望不会造成混淆!

您尝试做的是一种动态类型化,您将itemClass设置为在编译时[=57]的类型=] 除了它是 some class 类型之外,一无所知。

其核心 Swift 本质上是一种 静态类型 语言,它的工作原理是了解有关某物类型的所有信息,例如当某物被声明为具有特定的引用或值类型时;通过了解类型,例如当某物具有协议类型时;甚至什么都没有,例如当某些东西是不受约束的通用参数类型时 and 在所有这些情况下,可以做的事情在很大程度上受限于这些知识。

不支持变量类型;虽然有不太具体的类型,例如示例中的 AnyClass,在转换为该特定(已知编译时间)类型(使用 as?as! 之前,无法执行特定于实际运行时类型的操作

Swift 确实支持一些动态类型功能,特别是它支持 Objective-C 的部分——它既有静态类型的部分,也有动态类型的部分;但是这些并没有给你你在这里想要做的事情,即在运行时之前被转换为未知的类型。

您可能知道 Objective-C,一个简单的例子说明了两种语言在 static/dynamic 方法上的区别是调用 method/function 时发生的情况。对于 Objective-C 方法调度是动态的,编译后的代码执行 search 来实现方法,并且搜索可能 fail 导致运行时错误并中止。在 Swift 中(不包括它与 Objective-C 的互通),当一个函数被调用时,编译后的代码会进行 而非 搜索,已知该实现在编译时存在,并且绝对不会出现运行时错误并中止。

要执行您正在尝试的操作,您需要在 设计时 确定执行所需操作所需的类型(在本例中构建 NSDraggingItem)和无论您是绝对知道还是可能知道您拥有的值在运行时都将符合该类型。如果你绝对知道你可以使用as!转换,如果你错了它会中止执行,或者你可以使用as?它允许你测试成功并采取适当的行动,如果你有一些计划外的类型。

HTH

我会用Sweeper's suggestion and CRD的精彩评论给出我自己的答案。

源对象,符合粘贴板写入协议-NSPasteboardWriting;我授权它。目标铸造证实了这一点。我的问题是考虑 objC 的菜鸟案例,并在源与目标之间进行转换,但强制执行相同;我希望 ;-).

override func mouseDragged(with event: NSEvent) {
    let arrayController = self.dataSource as! NSArrayController
    let objects = arrayController.arrangedObjects as! [NSPasteboardWriting]
    let delegate = self.delegate as! NSViewController
    let indexSet = self.selectedRowIndexes
    var items = [NSDraggingItem]()

    for index in indexSet {
        let dragImage = (delegate.view.window?.windowController?.document as! Document).displayImage!
        let item = NSDraggingItem.init(pasteboardWriter: objects[index])
        item.setDraggingFrame(self.rect(ofRow: index), contents: dragImage)
        item.draggingFrame = self.rect(ofRow: index)
        items.append(item)
    }
    self.beginDraggingSession(with: items, event: event, source: self)
}