I am starting to convert an Obj-C project to Swift and am running into an issue when trying to implement a Swift version of + (nullable __kindof Foo) getFoo;*, which can return an instance of Foo or any subclass of Foo.
If I were working entirely in Swift, I would use something like class func getFoo<T: Foo>() -> T to get the same behavior, however the compiler complains about this ("method cannot be marked @objc because it has generic parameters").
At this point, it forces me to cast the method result every place it is used, i.e., someFoo = (SonOfFoo)SonOfFoo.getFoo*, so I was wondering if there is a language or other means of getting similar behavior.
Sorry, I was being generic (!) because there are a number of cases where methods return a subclass. Typically they are category and protocol class methods where the behavior is exactly the same but the returned class type varies.
class func getAllOfMe(in context: NSManagedObjectContext) -> [T] where T: NSManagedObject
let allFoos = Foo.getAllOfMe(in: context) // == [Foo]
If I try to get the “kindof” behavior in the Swift version replacing the Obj-C method, the compiler complains once about generics (cannot use generics with @objc). If I just return, i.e., [NSManagedObject], then I get a ton of incompatible pointer type warnings.
The migration process will proceed at a snail’s pace relative to other work, so there will be a mix of Swift and Obj-C for some time. I’m trying to avoid two things:
The need to go through and cast result types that didn’t need to be cast before; and
Keeping separate Obj-C and Swift versions of these methods to satisfy #1.
I could migrate as much as possible to Swift and bite the bullet on #2 for now, but I’m trying to avoid the case where something gets fixed in one method and not the other.
I don't remember offhand how I finally ended up handling it since it's been a while now. I did eventually get everything migrated over to Swift, though, so I probably just dealt with the in-progress mess.