0
protocol TestProtocol {
    init()
}

class Person: NSObject, TestProtocol {
    required override init() {
        super.init()
    }
}

class Man: Person {

}

class Women: Person {

}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let classes: [TestProtocol.Type] = [Person.self, Man.self, Women.self]

        classes.forEach { (type) in
            let obj = type.init()

            print(obj)
        }
    }
}

我尝试在 Xcode10.2 中执行这些代码,将 Swift 版本配置为 Swift5,我希望获得 Person、Man 和 Women 的实例,但控制台结果是:

<TestSwift5.Person: 0x6000006eb3e0>
<TestSwift5.Person: 0x6000006eb3e0>
<TestSwift5.Person: 0x6000006eb3e0>

这让我很困惑,任何人都可以解释它。

期待你的回答,谢谢。

4

1 回答 1

1

NSObject 与原生 Swift 子类的子类化有一些关键区别。

Swift 本机基类或 NSObject

我不是确切原因的专家,但它与 Objective-C 运行时以及您使用 NSObject 获得的额外元数据有关。

在您的示例中,如果您没有从 NSObject 子类化,您将看到控制台输出符合您的预期。

在使用表格视图和集合视图单元格时,我自己也遇到了这个问题。我尽量避免 NSObject 子类化,但当它不可避免时,我也会从CustomStringConvertibledescription自定义属性以获得我需要的东西。

您也可以使用反射等技术来充分利用这一点。

protocol TestProtocol {
    init()
}

class Person: TestProtocol {
    required init() {

    }
}

class Man: Person {
    required init() {
        super.init()
    }
}

class Women: Person {

}

当您在 Xcode 或 Playground 中运行它们时,您会得到以下信息:

__lldb_expr_16.Person
__lldb_expr_16.Man
__lldb_expr_16.Women

于 2019-04-15T18:54:02.947 回答