Yang
Yang

Reputation: 13

Subclassing Objective-C class with factory method in Swift, the generics doesn't work

I have a Base class with a factory method written in Objective-C.(some lib)

@interface Base : NSObject
@property(nonatomic, strong) NSString *content;
+ (instancetype)baseWithContent:(NSString *)content;
@end
//==================
@implementation Base
+ (instancetype)baseWithContent:(NSString *)content {
    Base* base = [[Base alloc]init];
    base.content = content;
    return base;
}
@end

Then I subclassing it in swift and casting it into AnyObject.(ignore the Bridging-Header part)

class Child: Base {}
var c = Child(content: "Child")
print("before casting", type(of:c))
print("after casting", type(of:c as AnyObject))

Get this strange result that it become a Base after casting.

before casting Optional<Child>
after casting Base

Actually if i use a designated initializer to override the generated-convenience initializer from objective-c, I get the right result.

class Child: Base {
    init?(content:String) {
        super.init()
        self.content = content
    }
}

before casting Optional<Child>
after casting Child

Am I making any mistake? Thanks for answering. I'm using Xcode Version 8.1 (8B62) and Swift 3.0.1

Upvotes: 1

Views: 241

Answers (1)

Sulthan
Sulthan

Reputation: 130112

Your factory method implementation in Obj-C is wrong. It always creates an instance of Base. To fix it:

+ (instancetype)baseWithContent:(NSString *)content {
    Base *base = [[self alloc] init]; //self instead of Base
    base.content = content;
    return base;
}

Basically, your factory method implementation doesn't match its return type, the result are type problems in Swift because Swift trusts type declarations.

Upvotes: 1

Related Questions