메서드(method)는 클래스(class), 구조체(struct), 열거형(enum)의 코드 안에서 정의된 함수(func)를 의미합니다.
클래스와 구조체에서 메서드는 속성(Property)과 다르게 사용하는 방법과 특징 그리고 종류가 조금 다릅니다. (클래스와 구조체는 메모리 할당 방식과 상속의 유/무가 다르기 때문에 이에 관련된 메서드가 존재합니다.)
가장 기본적인 메서드의 한 종류이며, 클래스 또는 구조체로부터 만들어진 객체(인스턴스)의 이름으로 접근하여 사용하는 메서드 입니다.
struct Man{ var name: String var age: Int init(name: String, age: Int){ self.name = name self.age = age } func hello(){ //인스턴스 메서드(Instance Methods) print("\(name): 안녕~!") } } var kim = Man(name: "김철수", age: 25) kim.hello() //인스턴스 메서드 호출(사용)
값 호출(call by value) 방식을 따르고 있는 구조체와 열거형은 프로퍼티를 수정하는 메서드를 사용 및 선언할 수 없습니다. (하지만 특별한 키워드를 사용하면 메서드를 통해 프로퍼티를 수정할 수 있습니다.)
참조에 의한 호출(call by reference) 방식을 따르고 있는 클래스의 경우에는 프로퍼티를 수정하는 메서드를 큰 문제 없이 사용할 수 있습니다.
mutating 키워드를 func 앞에 작성하면 구조체와 열거형도 메서드를 통해 프로퍼티를 수정할 수 있습니다.
구조체는 스택(stack)이라는 메모리 공간에 인스턴스의 프로퍼티 데이터를 저장하여 사용합니다. 스택에 할당된 프로퍼티의 데이터는 수정이 불가능하므로 원본값을 변경하고 싶을 때는 "mutating" 키워드를 사용해야 합니다.
이는 구조체의 프로퍼티 데이터 원본값을 변경하는 것이 아닌, 수정할 값을 복사해와서 사용하는 개념입니다.
즉, mutating 키워드를 사용했다 한들 value type은 스택 공간에서는 원본값을 수정하는 것이 불가능합니다. (복사해서 변경한 걸 사용하는 개념)
struct Man{ var name: String var age: Int init(n: String, age: Int){ self.name = n self.age = age } func hello(){ print("\(name): 안녕~!") } mutating func changeName(name: String){ self.name = name } } var kim = Man(n: "김철수", age: 25) kim.changeName(name: "신짱구") kim.hello()
하지만 클래스는 조금 다르다.
클래스는 힙(heap)이라는 메모리 공간에 인스턴스의 프로퍼티 데이터를 저장하며, 스택에는 데이터가 저장되어있는 힙의 주소를 할당해줍니다.
즉, 원본값을 변경하더라도 스택 영역의 주솟값을 변경하는 것이 아니기 때문에 "mutating" 키워드 없이 사용이 가능합니다.
class Man{ var name: String var age: Int init(n: String, age: Int){ self.name = n self.age = age } func hello(){ print("\(name): 안녕~!") } func changeName(name: String){ self.name = name } } var kim = Man(n: "김철수", age: 25) kim.changeName(name: "신짱구") kim.hello()
타입 메서드는 인스턴스가 접근하는 메서드가 아닌, 클래스나 구조체 타입이 직접 접근하여 사용하는 메서드입니다.
구조체의 경우에는 static 키워드만 사용 가능하며, 클래스의 경우에는 static 키워드와 class 키워드 모두 사용이 가능합니다. (static으로 상속받을 경우 재정의가 불가능)
class Man{ class var job: String = "학생" var name: String var age: Int init(n: String, age: Int){ self.name = n self.age = age } func hello(){ print("\(name): 안녕~!") } static func address(){ print("저는 \(Man.job)입니다. 서울특별시 떡잎마을에 거주하고 있습니다.") } } var kim = Man(n: "김철수", age: 25) Man.address() //저는 학생입니다. 서울특별시 떡잎마을에 거주하고 있습니다.
참고자료: 앨런 Swift문법 마스터 스쿨