특정 타입의 클래스, 구조체, 열거형과 관련된 함수를 메서드라 합니다. 특정 타입의 인스턴스에서 실행할 수 있는 메서드를 인스턴스 메서드, 특정 형과 관련된 메서드를 타입 메서드라 합니다. 타입 메서드는 Objective-C에서 클래스 메서드와 유사합니다. Swift에서 메서드가 C나 Objective-C 메서드 간의 가장 큰 차이는 바로 Objective-C에서는 클래스 타입에서만 메서드를 선언할 수 있다는 것 입니다. 반면 Swift에서는 클래스 타입 뿐만아니라 구조체, 열거형에서도 메서드를 선언해 사용할 수 있습니다.


Instance Methods(인스턴스 메서드)

인스턴스 메서드는 특정 클래스, 구조체, 열거형의 인스턴스에 속한 메서드입니다. 이 메서드를 통해 인스선트 내의 값을 제어하거나 변경할 수 있습니다. 인스턴스 메서드는 이름 그대로 그 인스턴스가 속한 특정 타입의 인스턴스에서만 실행 가능합니다.

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
    func increment(by amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}

//클래스를 사용한 예

let counter = Counter()
// 초기 count 값은 0입니다.
counter.increment()
// count 값이 1로 변경 됐습니다.
counter.increment(by: 5)
// count 값은 현재 6입니다.
counter.reset()
// count 값은 0이 됩니다.

<aside> 💡 인스턴스 메서드

오버로딩 지원

</aside>

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
    func increment(by amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}

//클래스를 사용한 예

let counter = Counter()
// 초기 count 값은 0입니다.
counter.increment()
// count 값이 1로 변경 됐습니다.
counter.increment(by: 5)
// count 값은 현재 6입니다.
counter.reset()
// count 값은 0이 됩니다.

The self Property(self 프로퍼티)

모든 프로퍼티는 암시적으로 인스턴스 자체를 의미하는 self라는 프로퍼티를 갖습니다. 인스턴스 메소드 안에서 self프로퍼티를 이용해 인스턴스 자체를 참조하는데 사용할 수 있습니다.

func increment() {
    self.count += 1
}

앞의 예제에서는 increment()메소드에서는 count += 1이라 표현했지만 사실은 self.count += 1의 의미 입니다. 이것이 가능한 이유는 Swift에서 특정 메소드에서 해당 인스턴스에 등록된 메소드나 프로퍼티를 호출하면 현재 인스턴스의 메소드나 프로퍼티를 사용하는 것으로 자동으로 가정하기 때문입니다. 위 규칙이 적용되지 않는 예외적인 상황이 있습니다. 바로 인자 이름이 프로퍼티 이름과 같은 경우 입니다. 이 경우에는 프로퍼티에 접근하기 위해 명시적으로 self키워드를 사용해야 합니다. 다음은 self키워드를 이용해 파라미터와 프로퍼티의 모호함을 명확하게 한 (예)입니다.

struct Point {
    var x = 0.0, y = 0.0
    func isToTheRightOf(x: Double) -> Bool {
        return self.x > x  // self.x를 이용해 프로퍼티 x와 인자 x를 구분
    }
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
    print("This point is to the right of the line where x == 1.0")
}
// "This point is to the right of the line where x == 1.0" 출력

isToTheRightOf(x: Double)메소드에서 self.x를 사용해 프로퍼티 x와 인자x를 구분했습니다. 만약 프로퍼티와 인자 이름이 같을 때 self키워드를 사용하지 않으면 Swift는 자동으로 인자 이름으로 가정합니다.

인스턴스 메서드 내에서 값 타입 변경(Modifying Value Typeds from Within Instance Methods)

구조체와 열거형은 값 타입입니다. 그래서 기본적으로 인스턴스 메서드 내에서 값 타입의 프로퍼티를 변경할 수 없습니다. 하지만 값타입 형의 메서드에서 프로퍼티를 변경하고 싶을 때가 있을 텐데 그럴때 메서드에 mutating 붙여 주면 가능합니다. mutating 이라는 키워드가 붙은 메서드에는 메서드의 계산이 끝난 후 원본 구조체에 그 결과를 덮어 써서 그 값을 변경합니다.

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\\(somePoint.x), \\(somePoint.y))")
// "The point is now at (3.0, 4.0)" 출력

let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// let으로 선언해서 값 변경 시도시 에러 발생!

Point는 구조체여서 메소드로 인스턴스의 값을 변경할 수 없지만 mutating func moveBy()같이 메소드 앞에 mutating을 붙여서 값을 변경할 수 있습니다. 한 가지 기억하실 부분은 여기서는 Point 인스턴스를 var somePoint로 선언해서 사용해서 가능했지만 만약 let somePoint으로 선언하면 구조체 단에서 변경이 불가능하다는 선언이기 때문에 mutating 선언과 상관없이 메소드로 값을 변경할 수 없습니다.