0

So this is a little tricky, but I'll outline the main points:

  • I have a class defined in an Objective-C header from a pre-compiled framework. We'll call BaseClass
  • This class is meant to be subclassed
  • BaseClass has a class function called fetchAll(), which can be called by a subclass to return an array of all instances of that subclass.

For example, SubClass.fetchAll() will return a Set<SubClass>

Now I want to write a new class function, called fetchAllNames()

Ideally, it would look like this:

extension BaseClass {
  class func fetchAllNoBilly() -> Set<Self> {
    return Self.fetchAll().filter{ return $0.name != "Billy" }
  }
}

then for one of my subclasses ,I could just say

Subclass.fetchAllNames() or SubClass3.fetchAllNames()

However, I get this compiler error:

'Self' is only available in a protocol or as the result of a method in a class; did you mean 'BaseClass'?

Is what I'm trying to do here possible? maybe it's just a bad pattern I shouldn't be doing, but right now we have a separate fetchAllNames() class func for every single subclass, that looks like this:

@objc(Subclass) final class Subclass: BaseClass {
  class func fetchAllNoBilly() -> Set<Self> {
    return Self.fetchAll().filter{ return $0.name != "Billy" }
  }
}

Which is just annoying to have that same class func in all ~20 of our subclasses

On top of that, there are other areas where we can reduce repeat code if I can figure out how to implement this pattern

A O
  • 5,516
  • 3
  • 33
  • 68
  • Possible duplicate of [Using 'self' in class extension functions in Swift](https://stackoverflow.com/questions/31165535/using-self-in-class-extension-functions-in-swift) – Cristik Aug 03 '18 at 05:23

1 Answers1

-1

Self is used to find the current instance, but in Class functions this is called on the class, not an instance of the class. What you should be doing is calling it on the class. Using your example you should be doing:

@objc(Subclass) final class Subclass: BaseClass {
  class func fetchAllNoBilly() -> Set<Subclass> {
    return Subclass.fetchAll().filter{ return $0.name != "Billy" }
  }
}
Sam
  • 956
  • 6
  • 12
  • Unfortunately the problem is that every subclass has the same method, so that `return` line is copy-pasted across all 20 of our subclasses' implementations-- that's why i was trying to extend the base class so everyone could reference the same implementation code – A O Aug 03 '18 at 21:52