As a brief follow-up to my previous post, I thought it would be helpful to enumerate the various types of “self” in Swift. It is an overloaded term. As we’ve seen, it can be quite confusing.
Prefix self.
The “prefix self”, or self.
, is the main self
, the primary self
— it is the self with which you are most familiar. Other programming languages call it this
and it refers to the instance of the enclosing type. You use it, either explicitly or implicitly, when referring to members of the enclosing type.
Example:
struct Person {
let name: String
init(name: String) {
self.name = name
}
}
Postfix .self
This version of self, the postfix .self
, refers to the metatype type of the type on which it is called.
From the Swift Programming Language Book:
You can use the postfix
self
expression to access a type as a value. For example,SomeClass.self
returnsSomeClass
itself, not an instance ofSomeClass
. AndSomeProtocol.self
returnsSomeProtocol
itself, not an instance of a type that conforms toSomeProtocol
at runtime.
Example:
class SomeClass { }
SomeClass.self
Self
Type
Capitalized Self
is not actually a type at all, but a “placeholder” for a specific type at runtime.
From the Swift Programming Language Book:
The
Self
type isn’t a specific type, but rather lets you conveniently refer to the current type without repeating or knowing that type’s name.In a protocol declaration or a protocol member declaration, the
Self
type refers to the eventual type that conforms to the protocol.
Example:
extension FloatingPoint {
static var one: Self {
Self(1)
}
}
// usage
Double.one
Float.one
CGFloat.one
- [NSObject self]
Ok, this one does not really have anything to do with Swift — except when it does. This was the culprit of the bug described in the previous post. This is the instance method self
on NSObject
, which is part of the Objective-C runtime. It exists in Swift because of the interoperability between the two languages. However, as we have seen, this is nothing but a nuisance in Swift when interfacing with subclasses of NSObject
.
Objective-C docs:
/// Returns the receiver.
- (instancetype)self;
// usage
[MyClass self];
Swift docs:
/// Returns the receiver.
func `self`() -> Self
// usage
MyClass.`self`