Look at a simple class like this:

class SomeClass {
    class func generate() -> SomeClass {
        return self.init()
    }
}

self is different in instance method and class method, you can see it through the auto completion of Xcode. In instance method, self’s type is SomeClass while in class method, it’s type is SomeClass.Type.

The compiler complains constructing an object of class type ‘SomeClass’ with a metatype value must use a ‘required’ initializer

How to understand this? If I write a subclass like this:

class SubClass: SomeClass {
    let aNumber: Int
    init(aNumber: Int) {
        self.aNumber = aNumber
        super.init()
    }
}

It will inherit SomeClass’s class method generate() but won’t inherit its default initializer init(). So SubClass.generate() actually calls SubClass(), but SubClass doesn’t have an initializer init()! Of course this is what the compiler want to prevent.

Then let’s move to a similar problem, it really took me some time to understand it.

class someClass {
}
var anotherClass = someClass.self
var anotherObject = anotherClass()

The compiler still complains constructing an object of class type ‘SomeClass’ with a metatype value must use a ‘required’ initializer.

It’s true that anotherClass is a metatype value, but what bad result will be caused?

Consider the case where we also have a subclass:

class SomeClass {
}

class Subclass : SomeClass {
}

If you store the class type in a variable:

var anotherClass = SomeClass.self

The variable anotherClass is of type SomeClass.Type.

You can later assign this variable a subclass:

anotherClass = SubClass.self

This is valid because SubClass.Type is a SomeClass.Type. At this point, anotherClass() would fail if the initializer is not implemented in the subclass. This is what the compiler is protecting against.

So, why does constructing an object of class type SomeClass with a metatype value must use a ‘required’ initializer?

Let’s say SubClass is a subclass of SomeClass. Since SubClass is still a SomeClass, it’s legal for SubClass to construct an object of class type SomeClass like SomeClass do but there’s no guarantee that SubClass has implemented the initializer which is used by SomeClass to do so. And the guarantee is the required initializer.

Thanks to Aaron Brager who answered my question on SOF and this question also helped a lot to understand this problem.