With a lot of help from the answer originally posted by @rintaro, I was able to solve this problem, although there is still a weirdness that I will post on a separate issue.
As it turns out, @rintaro was absolutely right in having to initialize an instance of a type type using the following syntax:
let result = (T.self as T.Type)(myRecord)
This works while the base class MyBaseClass declares this initializer with the required tag:
public class MyBaseClass { public required init(_ record:MyRecordType) { ... } }
and the subclass MySubClass implements the corresponding initializer:
public class MySubClass : MyBaseClass { public required init (_ record:MyRecordType) { ... super.init(record) } }
If something fails, however, when I really have a class hierarchy of 3 levels, and the initializer hierarchy through override to the mix. To represent this, consider a set of classes representing nodes in a tree structure:
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) -> ()) {
The problem occurs when implementing the RootNode class retrieveAll method. In order for it to work as described by @rintaro, I need init in the RootNode so that it is marked with the required keyword. But since it also overrides the initializer from Node , it must also have the override keyword. Therefore, I am trying to use both words in a declaration:
override required public init(_ record:MyRecordType) { ... }
The Swift compiler accepts this, but when I use it to initialize an instance from the retrieveAll method, it fails with BAD_ACCESS.
I managed to get around this problem by slightly changing the signature of the NodeClass method NodeClass that its subclass RootNode does not need to be redefined:
public class Node { public init(record:MyRecordType) { ... } } public class RootNode { public required init(_ record:MyRecordType) { ... super.init(record:record) } }
In this case, my RootNode subclasses can correctly implement the required initializer, and the retrieveAll method in RootNode can correctly instantiate these subclasses.