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
selfexpression to access a type as a value. For example,SomeClass.selfreturnsSomeClassitself, not an instance ofSomeClass. AndSomeProtocol.selfreturnsSomeProtocolitself, not an instance of a type that conforms toSomeProtocolat 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
Selftype 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
Selftype 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`