从字典创建一个Swift对象

5
在Swift中,如何根据字典中的查找值动态实例化类型?

1
不幸的是,您现在已经完全修改了问题。现在已经不清楚问题是什么以及这是解决方案的什么。最好还原到原始问题,并将答案作为答案而不是问题的编辑,它会覆盖原始问题。 - matt
是的,这不再是一个问题了。我现在把它变成了一个问题,这样好吗?还是我应该回去? - possen
1
基本上在Swift中你根本无法做到这一点。但是你可以在Objective-C中实现它,而Swift完全能够与Objective-C对象进行交互。请注意,任何继承NSObject的都不是Swift对象,而是Objective-C对象。它们的行为大多相同,但Objective-C对象能够具有动态性,但也有其他缺点(例如:速度较慢)。 - Abhi Beckert
1
Abhi,我在测试中将NSObject作为基类删除了,它仍然可以工作。 - possen
1
即使编辑后,这个“问题”仍然是一个带答案的问题。也就是说,“问题”中的代码示例并没有展示出任何问题,而是问题的答案。下面的回答并没有提供答案,而是对问题中包含的答案进行了评论。我建议编辑“问题”,以便读者明显地看到它已经被编辑过,并且是自问自答的形式。通过遵循惯例来帮助读者。 - bootchk
感谢您的反馈。我不太记得我第一次提出问题时到底写了什么。因此,希望我将答案移动到答案部分的这个编辑能更有意义。 - possen
1个回答

4

希望这对其他人有用。需要一定的研究才能弄清楚这一点。目标是避免使用巨大的if或switch语句从值创建每个对象类型的反模式。

class NamedItem : CustomStringConvertible {
    let name : String

    required init() {
        self.name = "Base"
    }

    init(name : String) {
        self.name = name
    }

    var description : String { // implement Printable
        return name
    }
}

class File : NamedItem {
    required init() {
        super.init(name: "File")
    }
}

class Folder : NamedItem {
    required init() {
        super.init(name: "Folder")
    }
}

// using self to instantiate.
let y = Folder.self
"\(y.init())"

let z = File.self
"\(z.init())"

// now put it in a dictionary.
enum NamedItemType {
    case folder
    case file
}

var typeMap : [NamedItemType : NamedItem.Type] = [.folder : Folder.self,
                                                  .file : File.self]
let p = typeMap[.folder]
"\(p!.init())"
let q = typeMap[.file]
"\(q!.init())"

有趣的方面:

  • 使用“required”初始化器
  • 使用.Type获取字典值的类型。
  • 使用.self获取可实例化的“class”
  • 使用()来实例化动态对象。
  • 使用Printable协议来获取隐式字符串值。
  • 如何使用非参数化初始化并从子类初始化中获取值。

更新为Swift 3.0语法


2
我觉得这很有启发性。谢谢你分享你的研究。 - vacawama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接