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

Swift 无法为泛型类型的子类调用初始值设定项,swift,generics,Swift,Generics,更新:问题和标题已根据回应初始问题所做的更改进行了重述 我有一个基类,它实现了创建新实例的泛型类方法。该类方法的简化逻辑如下 class MyBaseClass { required init(_ record:MyRecordType) { println("Entered MyBaseClass.init") // Initialize base class from record } class func retrieveIns

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


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

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 AnotherClass {
    func successCallback(result:MySubclass) {
        // Handle callback
    }
    MySubClass.retrieveInstance("objectName", callback:successCallback)
}
在创建类的实例时(用标识崩溃位置的注释标记的行),我希望调用
MySubClass
中的init方法。(这种奇怪的表示法基于回复中建议的bug解决方法)


此代码不是为
MySubClass
调用
init
方法,而是由于访问错误而崩溃。我一直找不到任何零引用或任何其他可以解释这次崩溃的东西。

在@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)
    }
}
然而,失败的地方是,我实际上有一个三级类层次结构,初始化器层次结构通过一个
覆盖
进入混合。要设想这一点,考虑一组表示树结构中节点的类:

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
    {
}
Swift编译器接受这一点,但当我使用它从
retrieveAll
方法中初始化实例时,它会因访问错误而崩溃

我可以通过稍微更改
NodeClass
的方法签名来解决这个问题,这样它的
RootNode
子类就不需要重写:

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

通过这样做,我的
RootNode
子类可以正确地实现所需的初始值设定项,而
RootNode
中的
retrieveAll
方法可以正确地实例化这些子类的实例。

我无法重现错误的访问。我假设您正在使用某个异步调用,可能问题就在那里。@rintaro-我终于能够找出问题所在。事实证明,它与异步无关,而是与混合重写的初始值设定项和所需的初始值设定项有关(我将在下面发布完整的描述)。因为你的答案至少让我指出了正确的方向,我想在这里给你正确的答案,但你似乎已经删除了你的答案。如果您想让我感谢您的帮助,请随时重新发布。一旦您在基类和子类上添加了所需的初始值设定项,您就可以使用
T()
@seanwoodward-不幸的是,这似乎不是真的。当我使用T(myRecord)调用初始值设定项时,它失败了,当我按照rintaro建议的方式调用它时。T(myRecord)的失败似乎是因为在获取实例的“record”属性时发生了错误的访问异常,该属性本应设置为传入的“myRecord”值。感谢您注意到这一点。对泛型初始值设定项
T()
的调用在简单测试中对我有效。我希望这些问题能在编译器的未来版本中得到解决。据我所知,init函数必须有“必需”的说明符,否则它将无法工作。
override required public init(_ record:MyRecordType) {
    ...
}
public class Node {
    public init(record:MyRecordType) {
        ...
    }
}
public class RootNode {
    public required init(_ record:MyRecordType) {
        ...
        super.init(record:record)
    }
}