无法将 MyClass 类型的值转换为 MyDelegate
Cannot cast value of type MyClass to MyDelegate
我有一个 class 需要将组件设置为 self
。该组件需要 class 来实现 protocol
MyDelegate。最终,它失败了 (SIGNAL 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() {
}
}
为什么?
不需要类型转换。由于 MyClass
采用 MyDelegate
它 是 也是 MyDelegate
.
并延迟初始化 属性 以便能够在顶层使用 self
。
private lazy var myComponent = Component(requiresAnObjectofTypeMyDelegate: self)
问题是 self
在存储的 属性 myComponent
中的用法。
通常,在初始化程序完成整个对象的初始化之前,不允许分发 self
。因此,您的问题与协议或扩展无关。更简单:
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
子类化,则会出现编译器错误:
use of unresolved identifier 'self'
Component(requiresAnObjectofTypeMyClass : self as! MyClass)
这表明问题所在:您不能在此处使用 self
。
我认为这只是一个 Xcode 错误; Xcode 似乎忽略了继承 NSObject
时的语法错误。强制转换 as! MyClass
也暗示我们正在寻找一种奇怪的解决方法,最终 Xcode 屈服并导致运行时崩溃。
要解决这个问题,您可以创建一个惰性 属性,它将在初始化过程之后进行评估,因此将允许 self
被传递给 Component
初始化程序:
private(set) lazy var myComponent = Component(requiresAnObjectofTypeMyClass:self)
在这里,你也不需要强制转换。不幸的是,swift 中不允许 lazy let
(没人知道为什么),所以 private(set)
接近它的语义。
将此代码转移到您的协议示例中很容易。
我有一个 class 需要将组件设置为 self
。该组件需要 class 来实现 protocol
MyDelegate。最终,它失败了 (SIGNAL 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() {
}
}
为什么?
不需要类型转换。由于 MyClass
采用 MyDelegate
它 是 也是 MyDelegate
.
并延迟初始化 属性 以便能够在顶层使用 self
。
private lazy var myComponent = Component(requiresAnObjectofTypeMyDelegate: self)
问题是 self
在存储的 属性 myComponent
中的用法。
通常,在初始化程序完成整个对象的初始化之前,不允许分发 self
。因此,您的问题与协议或扩展无关。更简单:
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
子类化,则会出现编译器错误:
use of unresolved identifier 'self' Component(requiresAnObjectofTypeMyClass : self as! MyClass)
这表明问题所在:您不能在此处使用 self
。
我认为这只是一个 Xcode 错误; Xcode 似乎忽略了继承 NSObject
时的语法错误。强制转换 as! MyClass
也暗示我们正在寻找一种奇怪的解决方法,最终 Xcode 屈服并导致运行时崩溃。
要解决这个问题,您可以创建一个惰性 属性,它将在初始化过程之后进行评估,因此将允许 self
被传递给 Component
初始化程序:
private(set) lazy var myComponent = Component(requiresAnObjectofTypeMyClass:self)
在这里,你也不需要强制转换。不幸的是,swift 中不允许 lazy let
(没人知道为什么),所以 private(set)
接近它的语义。
将此代码转移到您的协议示例中很容易。