代码之家  ›  专栏  ›  技术社区  ›  Kheldar haccks

无法将MyClass类型的值强制转换为MyDelegate

  •  0
  • Kheldar haccks  · 技术社区  · 7 年前

    我有一个类需要将组件设置为 self . 该组件要求类实现 protocol My委托 . 最后,它失败了(信号SIGABRT)。

    // I need the class to be a NSObject for unrelated requirements 
    class MyClass: NSObject {
    
    // I force the compilation, but it then breaks apart at runtime anyway
     private let myComponent = 
     Component(requiresAnObjectofTypeMyDelegate: self as! MyDelegate) 
    }
    
    // in the same file 
     extension MyClass: MyDelegate {  
       func myUsefulDelegateCall() {
       } 
     }
    

    为什么?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Andreas Oetjen    7 年前

    问题在于 self 在存储的属性中 myComponent . 通常,不允许分发 自己 在初始化器完成初始化整个对象之前。因此,您的问题与协议或扩展无关。更简单:

    import Foundation
    
    
    class Component {
        init(requiresAnObjectofTypeMyClass:MyClass) {
        }
    }
    
    // I need the class to be a NSObject for unrelated requirements 
    class MyClass : NSObject {
    
        // I force the compilation, but it then breaks apart at runtime anyway
        private let  myComponent = 
            Component(requiresAnObjectofTypeMyClass : self as! MyClass)
    }
    
    let m = MyClass()
    

    也崩溃了。

    如果你把 NSObject 子类化,您会得到一个编译器错误:

    使用未解析的标识符“self” 组件(RequiresObjectofTypeMyClass:Self-as!MyClass)

    这说明了问题:您不能使用 自己 在这里。 我认为这只是一个Xcode错误;Xcode在子类化时似乎忽略了语法错误。 N对象 . 演员阵容 as! MyClass 这也是一个提示,我们正在寻找一个奇怪的解决方案,最终得到的Xcode到它的膝盖,并导致运行时崩溃。

    为了解决这个问题,您可以创建一个lazy属性,该属性将在初始化过程后进行评估,因此允许 自己 交给 Component initializer:

    private(set) lazy var  myComponent = Component(requiresAnObjectofTypeMyClass:self)
    

    在这里,你也不需要演员表。不幸的是, lazy let 不允许使用斯威夫特(也没人知道为什么),所以 private(set) 接近它的语义。

    将此代码传输到协议示例很容易。

        2
  •  1
  •   vadian    7 年前

    不需要类型转换。AS MyClass 采用 MyDelegate My委托 .

    并延迟初始化属性以便能够使用 self 在最高层。

    private lazy var myComponent = Component(requiresAnObjectofTypeMyDelegate: self)