【问题标题】:weird result of init some instance in swift5?在 swift5 中初始化某些实例的奇怪结果?
【发布时间】:2019-04-15 13:55:29
【问题描述】:
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>

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

期待您的回答,谢谢。

【问题讨论】:

    标签: protocols nsobject swift5 xcode10.2


    【解决方案1】:

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

    Swift native base class or NSObject

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

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

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

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

    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
    
    

    【讨论】:

      猜你喜欢
      • 2013-11-17
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多