In an iOS framework, if I create a public class with an internal superclass, I get an error:
internal class Animal { }
public class Dog: Animal {
var name: String
public init(name: String) {
self.name = name
}
}
Error: Class cannot be declared public because its superclass is internal
This makes sense. However, if I do the same thing but use a generic in the class declaration, no error is shown.
internal class Car<Type: Equatable> { }
public class Camry<Type: Equatable>: Car<Type> {
var name: String
public init(name: String) {
self.name = name
}
}
Is this just a bug? Should both of these examples actually be giving an error?
If you include the framework in a project, you can use the Camry
class just fine, and the app will build and run on both a simulator and a device. However, I've noticed in certain cases that if you try to archive an app with these internal generic classes, you will sometimes get a Mach-O Linker Error.
Undefined symbols for architecture arm64
I haven't been able to nail down exactly why this occasionally happens though.
EDIT: The linker error happens when you have a public initializer in the internal class. So it is allowed to include code like this in a framework:
internal class Car<Type: Equatable> {
var wheels: Type
public init(wheels: Type) {
self.wheels = wheels
}
}
public class Camry<Type: Equatable>: Car<Type> {
var name: String
public init(name: String, wheels: Type) {
self.name = name
super.init(wheels: wheels)
}
}
And you could use Camry<Int>(name: "My Camry", wheels: 4)
without a problem in an app that included that framework, but when you try to archive the project, you'll get a linker error.
As suggested by Rob Napier, this is indeed a bug. It was accepted as issue SR-6206 on bugs.swift.org and should be fixed in Swift 4.1.