gpt4 book ai didi

swift - 无法为泛型类型的子类调用初始值设定项

转载 作者:搜寻专家 更新时间:2023-10-30 22:13:10 26 4
gpt4 key购买 nike

更新:问题和标题已根据针对初始问题所做的更改进行了重述。


我有一个基类,它实现了一个用于创建新实例的通用类方法。该类方法的简化逻辑如下

class MyBaseClass {

required init(_ record:MyRecordType) {
println("Entered MyBaseClass.init")
// Initialize base class from record
}

class func retrieveInstance<T:MyBaseClass>(name:String, callback:(T) -> ()) {
let myRecord:MyRecordType = ... // Perform fetch to get a record for name
let result = (T.self as T.Type)(myRecord) // Code currently crashes with BAD_ACCESS at this line
callback(result)
}
}

然后我使用如下逻辑实现这个基类的子类

class MySubClass : MyBaseClass {

required init(_ record:MyRecordType) {
println("Entered MySubClass.init")
// Initialize subclass from record
super.init(record)
}
}

接下来,我尝试调用泛型类方法

class AnotherClass {
func successCallback(result:MySubclass) {
// Handle callback
}
MySubClass.retrieveInstance("objectName", callback:successCallback)
}

当创建类的实例时——标有标识崩溃位置的注释的行——我希望调用 MySubClass 中的 init 方法。 (这个奇怪的符号是基于回复中建议的错误解决方法)

此代码没有为 MySubClass 调用 init 方法,而是因 BAD_ACCESS 而崩溃。我找不到任何 nil 引用或任何其他可以解释此崩溃的内容。

最佳答案

在@rintaro 最初发布的答案的大量帮助下,我能够解决这个问题,尽管我将在一个单独的问题下发布一个奇怪的问题。

事实证明,@rintaro 在需要使用以下语法初始化泛型类型的实例方面是绝对正确的:

let result = (T.self as T.Type)(myRecord)

只要基类 MyBaseClass 使用 required 标记声明此初始化程序,这就有效:

public class MyBaseClass {
public required init(_ record:MyRecordType) {
...
}
}

并且子类 MySubClass 实现了匹配的初始化器:

public class MySubClass : MyBaseClass {
public required init (_ record:MyRecordType) {
...
super.init(record)
}
}

然而,事情失败的地方是当我实际上有一个 3 级类层次结构时,初始化器层次结构通过 override 进入混合。为了设想这一点,考虑一组表示树结构中节点的类:

public class Node {
public init(_ record:MyRecordType) {
...
}
}

public class RootNode : Node {
override public init(_ record:MyRecordType) {
...
super.init(record)
}
public class func <T:RootNode>retrieveAll(success:(T) -> ()) {
// Retrieve all instances of root node subclass T, and invoke success callback with new T instance
}
}

public class ChildNode : Node {
public init(_ record:MyRecordType, parentNode:Node) {
...
super.init(record)
}
public class func <T:ChildNode>retrieveChildren(parent:Node, success:(T) -> ()) {
// Retrieve all child T instances of parent node, and invoke success callback with new T instance
{
}

问题发生在RootNode 类的retrieveAll 方法的实现中。为了使其按照@rintaro 的描述工作,我需要在 RootNode 中的 init 标记 required 关键字。但是因为它也覆盖了 Node 的初始化器,所以它也需要有 override 关键字。所以我尝试在声明中同时使用这两个关键字:

override required public init(_ record:MyRecordType) {
...
}

Swift 编译器接受这个,但是当我用它从 retrieveAll 方法中初始化一个实例时,它崩溃并返回 BAD_ACCESS。

我能够通过稍微更改 NodeClass 的方法签名来解决这个问题,这样它的 RootNode 子类就不需要覆盖:

public class Node {
public init(record:MyRecordType) {
...
}
}
public class RootNode {
public required init(_ record:MyRecordType) {
...
super.init(record:record)
}
}

通过这种解决方法,我的 RootNode 子类可以正确实现所需的初始化程序,并且 RootNode 中的 retrieveAll 方法可以正确实例化实例这些子类。

关于swift - 无法为泛型类型的子类调用初始值设定项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27117921/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com