[Swift 5.1] .Self 키워드
swift-evolution/0068-universal-self.md at master · apple/swift-evolution
Self 는 원래 자기 자신의 동적 클래스 (dynamic class) 를 가리키는 키워드 입니다.
class MyClass {
class var name: String {
return "unknown name"
}
func show() {
print("My name is \\(MyClass.name)")
}
}
class AnotherClass: MyClass {
override class var name: String {
return "another name"
}
}
let obj = AnotherClass()
obj.show() // "unknown name"
이 상황에서 MyClass 의 자식클래스에서 show() 메서도를 그대로 사용하면서 클래스 변수인 name만들 오버라이드하고 싶을때
Swift 5.1에서는 이를 상속받은 클래스에서 정의하는 class 맴버(혹은 static 맴버)를 참조할 수 있도록 Self키워드에 능력이 추가됩니다. 따라서 위의 MyClass의 Show() 메서드를 아래와 같이 수정할 수 있습니다.
func show() {
print("My name is \\(Self.name)")
}
이렇게 하면 이제 AnotherClass 의 인스턴스에서 show() 메서드를 호출하려면 의도대로 “another name”이 콘솔에 표시 됩니다. 이런식으로 Self키워드를 사용할 수 있습니다.
Self는 이외에도 여러 용도로 활용됩니다. 아래처럼 상속 대신 프로토콜에 맞춰 구현한 구조체 (struct)도 static 맴버 엑세스 하기 위해 Self를 사용할 수 있습니다.
protocol MyType {
static var name: String { get }
func show()
}
extension MyType {
func show() {
print("My name is \\(Self.name)")
}
}
struct John: MyType {
static var name = "John"
}
struct Conrad: MyType {
static var name = "Conrad"
}
let j = John()
j.show() // "John"
let c = Conrad()
c.show() // "Conrad"
extension을 이용해 MyType의 show() 메서드를 직접 구현한 경우 이 녀석도 실제를 구현하는 값을 참조하도록 Self 키워드를 사용한 예제 입니다.
Self는 class, struct, enum 내부에서 사용될 때 포함하는 유형을 참조하도록 Swift의 사용을 확장합니다.
이것은 런타임에 정확한 유형을 결정해야 하는 동적 유형에 특히 유용합니다. 예를 들어
class NetworkManager {
class var maximumActiveRequests: Int {
return 4
}
func printDebugData() {
print("Maximum network requests: \\(NetworkManager.maximumActiveRequests).")
}
}
**maximumActiveRequests**네트워크 관리자에 대한 정적 속성을 선언하고 정적 속성
**printDebugData()**을 인쇄하는 메서드를 추가합니다.
지금은 잘 작동하지만 **NetworkManager**하위 클래스가 지정되면 상황이 더 복잡해집니다.
class ThrottledNetworkManager: NetworkManager {
override class var maximumActiveRequests: Int {
return 1
}
}
maximumActiveRequests 해당 하위 클래스는 한번에 하나의 요청만 허용하도록 변경 되지만 printDebugData() 를 호출하면 상위 클래스의 값이 출력됩니다.
let manager = ThrottledNetworkManager()
manager.printDebugData() // print : 4
ThrottledNetworkManager 에서 override한 maximumActiveRequests 를 호출하고 싶다면
class ImprovedNetworkManager {
class var maximumActiveRequests: Int {
return 4
}
func printDebugData() {
print("Maximum network requests: \\(Self.maximumActiveRequests).")
}
}
위와 같이 작성하면 됩니다.
Self 키워드를 사용하면 됩니다.