Tunko Development Diary

[Swift 5.1] .Self 키워드 본문

Development/iOS 개발

[Swift 5.1] .Self 키워드

Tunko 2022. 8. 27. 07:51

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 키워드를 사용하면 됩니다.

Universal Self

반응형
Comments