인스턴스 또는 타입의 부분인 함수를 정의하고 호출한다.
메서드 (Methods) 는 특정 타입과 연관된 함수이다. 클래스, 구조체, 그리고 열거형은 주어진 타입의 인스턴스 동작을 위한 특정 작업과 기능을 캡슐화하는 인스턴스 메서드를 정의할 수 있다. 클래스, 구조체, 그리고 열거형은 타입 자체와 연관된 타입 메서드를 정의할 수도 있다. 타입 메서드는 Objective-C에서 클래스 메서드와 유사하다.
Swift에서 구조체와 열거형에 메서드를 정의할 수 있다는 사실은 C와 Objective-C와의 가장 큰 차이점이다. Objective-C에서 클래스는 메서드만 정의할 수 있는 유일한 타입이다. Swift에서는 클래스, 구조체, 또는 열거형을 정의할 지 선택할 수 있으며 생성한 타입에 대한 메서드를 유연하게 정의할 수 있다.
인스턴스 메서드 (Instance methods) 는 특정 클래스, 구조체, 또는 열거형의 인스턴스에 속하는 함수이다. 인스턴스 프로퍼티에 접근하고 수정하는 방법을 제공하거나 인스턴스의 목적과 관련된 기능을 제공한다. 인스턴스 메서드는 함수 (Functions) 에서 설명한 대로 함수 구문과 완벽하게 동일하다.
인스턴스 메서드는 속하는 타입의 중괄호 내에 작성한다. 인스턴스 메서드는 다른 인스턴스 메서드와 타입의 프로퍼티에 암시적으로 접근할 수 있다. 인스턴스 메서드는 자신이 속한 타입의 특정 인스턴스에서만 호출될 수 있다. 기존 인스턴스 없이는 호출할 수 없다.
다음은 작업이 발생한 횟수를 계산하는데 사용할 수 있는 간단한 Counter 클래스 정의의 예이다:
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
Counter 클래스는 3개의 인스턴스 메서드를 정의한다:
increment() 는 1 씩 카운터를 증가시킨다.
increment(by: Int) 는 특정 정수 크기만큼 카운터를 증가시킨다.
reset() 은 카운터를 0으로 재설정한다.
Counter 클래스는 현재 카운터 값을 추적하는 count 프로퍼티 변수도 선언한다.
프로퍼티와 동일하게 점 구문으로 인스턴스 메서드를 호출한다:
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by: 5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0
함수 파라미터는 함수의 본문 내에서 사용하는 이름과 함수를 호출할 때 사용하는 인수 라벨 둘다 가질 수 있습니다. 메서드는 타입과 관련된 함수이므로 메서드 파라미터도 동일하게 적용된다.
타입의 모든 인스턴스는 인스턴스 자체와 정확하게 일치하는 self 라는 암시적 프로퍼티를 가지고 있다. 자체 인스턴스 메서드 내에서 현재 인스턴스를 참조하기 위해 self 프로퍼티를 사용한다.
위 예제에서 increment() 메서드는 아래와 같이 작성될 수 있다:
func increment() {
self.count += 1
}
실제로 코드에서 self 를 꼭 작성할 필요가 없다. self 를 명시적으로 작성하지 않으면 Swift는 메서드 내에서 이미 알고 있는 프로퍼티 또는 메서드 이름을 사용할 때마다 현재 인스턴스의 프로퍼티 또는 메서드를 참조한다고 가정한다. 이 가정은 Counter 에 3개의 인스턴스 메서드 내에서 self.count 가 아닌 count 를 사용하여 입증된다.
이 규칙의 주요 예외사항은 인스턴스 메서드에 파라미터 명이 그 인스턴스에 프로퍼티 명과 동일할 때 발생한다. 이러한 경우 파라미터 명이 더 우선시 되고 프로퍼티를 참조하려면 더 규정된 방식으로 참조해야 한다. 파라미터 명과 프로퍼티 명을 분리하기 위해 self 프로퍼티를 사용한다.
여기서 self 는 x라는 메서드 파라미터와 x라고 하는 인스턴스 프로퍼티를 명확하게 한다:
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.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")
}
// Prints "This point is to the right of the line where x == 1.0"
self 접두사가 없으면 Swift는 x 의 2가지 사용이 모두 x 라는 메서드 파라미터를 참조한다고 가정한다.
구조체와 열거형은 값 타입이다. 기본적으로 값 타입의 프로퍼티는 인스턴스 메서드 내에서 수정될 수 없다.
그러나 특정 메서드 내에서 구조체나 열거형의 프로퍼티 수정이 필요하다면 해당 메서드에 대한 동작을 변경 하도록 선택할 수 있다. 그러면 이 메서드는 메서드 내에서 프로퍼티를 변경할 수 있고 메서드가 끝나면 기존 구조체에 변경사항이 작성된다. 이 메서드는 암시적 self 프로퍼티에 새로운 인스턴스를 할당하고 새로운 인스턴스는 메서드가 종료되면 기존에 존재하던 인스턴스를 대체하게 된다.
해당 메서드는 func 키워드 전에 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))")
// Prints "The point is now at (3.0, 4.0)"
위의 Point 구조체는 포함한 양만큼 Point 인스턴스를 이동시키는 변경가능한 moveBy(x:y:) 메서드를 정의한다. 새로운 위치를 반환하는 대신에 이 메서드는 실제로 호출된 위치를 수정한다. mutating 키워드는 프로퍼티를 수정할 수 있도록 정의에 추가된다.
프로퍼티가 프로퍼티 변수이더라도 변경할 수 없기 때문에 구조체 타입의 상수에 대해 변경 메서드를 호출할 수 없다:
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// this will report an error
변경 메서드 (Mutating methods)는 암시적 self 프로퍼티를 완전히 새로운 인스턴스로 할당할 수 있다. 위에서 본 Point 예제는 대신 다음과 같은 방식으로 작성되었을 수도 있다:
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
이 버전의 변경가능한 moveBy(x:y:) 메서드는 x 와 y 값이 대상 위치로 설정된 새로운 구조체를 생성한다. 이 대체 버전의 메서드를 호출한 최종 결과는 이전 버전의 호출 결과와 동일하다.
열거형의 변경 메서드는 동일한 열거형에서 다른 케이스로 암시적으로 self 파라미터를 설정할 수 있다:
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off
이 예제는 3개의 상태를 나타내는 스위치를 열거형으로 정의한다. 이 스위치는 next() 메서드가 호출될 때마다 3개의 전원 상태 (off, low, high)를 순환한다.