Swift Declare Class Func in Protocol

hris.to picture hris.to · May 14, 2015 · Viewed 12k times · Source

I had following confusion. As far as I know the main difference between static and class keywords when declaring method is that the second one could be overridden in subclasses.

The problem

However when I declare a protocol in Swift 1.2 like this:

protocol MyProtocol
{
    class func dummyClassMethod()
}

compiler gives an error:

Class methods are only allowed within classes; use 'static' to declare a static method

The error is pretty descriptive as obviously MyProtocol is not a class, however I want to make a class func part of the protocol.

What I've tried

I've found that if I declare interface in protocol as static, compiler is happy and I could use this static method in all classes that adopt this protocol:

protocol MyProtocol
{
    static func dummyClassMethod()
}

The question

So my question basically is is this right? This declaration states that my class method cannot be overridden in children, however in my implementation I could write and use the following:

class ClassA: MyProtocol
{
    class func dummyClassMethod() {

    }
}

class ClassB: ClassA
{
    override class func dummyClassMethod() {

    }
}

and now my dummyClassMethod is not static anymore...

  1. Compiler is Ok and everything works - but why?

  2. Is it specific to the fact that interface itself is static, however it's implementation is not?

  3. Is there a better alternative for class func in protocols?

Objective-C solution

In ObjC this is pretty easy and compile & run flawlessly:

@protocol MyProtocol 

+(void)dummyClassMethod;

@end

Answer

eMdOS picture eMdOS · Jun 27, 2015

You can review Apple's Documentation (subsection Method Requirements).

There says:

As with type property requirements, you always prefix type method requirements with the static keyword when they are defined in a protocol. This is true even though type method requirements are prefixed with the class or static keyword when implemented by a class

In practice, You can do it as follow:

First, declare your protocol:

protocol SomeProtocol {
    static func someMethod()
}

Then, in your class you've 2 options:

First:

class SomeClass : SomeProtocol {
    class func someMethod()
}

Second:

class SomeClass : SomeProtocol {
    static func someMethod()
}

I hope, this may clarify your doubt..