← 메인으로

0805-3 Self

객체지향 프로그래밍 언어에 익숙하다면 현재의 클래스 인스턴스에 속한 메서드나 프로퍼티를 가리킬 때 프로퍼티와 메서드 앞에 self를 붙이는 습관이 있을 것이다. 스위프트 언어 역시 그렇게 사용하기 위한 self 프로퍼티 타입을 제공한다. 따라서 다음은 완벽하게 유효한 코드다.

class MyClass { var myNumber = 1 func addTen() { self.myNumber += 10 // 해당 클래스 인스턴스에 속한 myNumber에 접근 } } 
class MyClass { var myNumber = 1 func addTen() { myNumber += 10 // self 생략했다 } } 
document?.openWithCompetionHandler({(success: Bool) -> Void in if success { self.ubiquityURL = resultURL } }) 
class MyClass { var myNumber = 10 // 클래스 프로퍼티 func addTen(myNumber: Int) { print(myNumber) // 함수의 매개변수 값을 출력 print(self.myNumber) // 클래스 프로퍼티 값을 출력 } } 

[!note] 느낌은 온다. 근데 확 이해되는 느낌이 아니다. 어지럽다. 지피티를 통해 한 번 더 이해하고 가자.

내가 헷갈리는 포인트


self: 지금 이 클래스의 인스턴스에 있는 프로퍼티라는 뜻을 가진다.

대부분의 경우 self는 생략 가능하다

class MyClass { var myNumber = 1 func addTen() { myNumber += 10 // self 없어도 문제 없음 } } 
func update(myNumber: Int) { print(myNumber) // 매개변수 print(self.myNumber) // 클래스 속성 } 

클로저 안에서는 항상 self를 써야 하는 이유

[[0805-2 클로저]]

someFunction { self.doSomething() } 

클로저는 캡쳐라는 메커니즘을 통해 바깥 변수를 저장해서 나중에 사용한다. 그래서 Swift는 "이건 외부 인스턴스를 참조하는구나"를 명확히 하기 위해 self를 강제로 쓰게 한다.

class TimerClass { var count = 0 func start() { Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in self.count += 1 print("카운트: \(self.count)") } } } 

시각적으로 표현하면

class Dog { var name = "Coco" func rename(name: String) { print(name) // 매개변수 print(self.name) // 클래스 속성 } } 

너가 넘겨준 이름은 name이고, 이 인스턴스 안에 있는 원래 이름은 self.name이야.

self는 생략할 수 있어도, 의도를 명확히 보이게 쓰기도 한다