Method : 특정 type 과 관련있는 fuction.
Obj-C 에서는 class 만 method 를 정의할 수 있었지만 Swfit 에서는 class, struct, enum 모두 method 를 정의할 수 있음.
Instance method : 특정 class/struct/enum 의 인스턴스에 속하는 function. Function 과 완전히 같은 문법을 가짐
Instance method 는 해당 타입의 모든 다른 instance method 와 property 에 대한 암묵적인 접근을 얻음. 속하는 type 의 instance 에서만 호출될 수 있으며 instance 없이 독립적으로 존재할 수 없음
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
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
특정 타입의 모든 instance 는 해당 instance 와 완전히 동일한 암묵적인 self property 를 가짐. Instance method 안에서 자신(instance) 를 참조할 수 있음.
실제로 self 를 직접 쓸 일은 많지 않음. 만약 명시적으로 self 를 쓰지 않는다면 Swift 는 method 안에서 property 나 method 를 호출할 때 해당 instance 의 property 나 method 를 쓴다고 가정함. 하지만 instance method 의 parameter 이름이 property 의 이름과 같은 경우에는 parameter 가 우선순위를 가지게 됨
func increment() {
self.count += 1
}
struct Point {
var x = 0.0, y = 0.0
// parameter name == property name. Parameter 가 우선순위를 가짐
func isToTheRightOf(x: Double) -> Bool {
return self.x > x // 우측의 x 는 parameter
}
}
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".
Struct, enum 은 value type 으로, 기본적으로 value type 의 property 는 instance method 안에서 수정될 수 없음.
mutating 을 써서 method 내부에서 struct/enum 의 property 를 수정할 수 있게 할 수 있음
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)".
Mutating method 는 암묵적인 self property 에 완전히 새로운 instance 를 할당할 수도 있음.
아래와 같이 작성한느 것은 위의 mutating function 에서 property 를 바꾼 것과 완전히 같은 결과를 보여줌
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)
}
}
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
static 키워드를 func 키워드 전에 써서 Type 자체에서 호출될 수 있는 method 를 정의 가능. Class 의 경우 class 키워드를 써서 subclass 가 superclass 의 type emthod 를 override 할 수 있게 함
class A {
class func someFunction() {
print("A")
}
}
class B: A {
override static func someFunction() {
print("B")
}
}
Type method 의 body 에서 암묵적 self property 는 type 자체를 말함. 이는 self 를 사용해서 type property 와 type method parameter 를 구분할 수 있음.
Type method 안에서 사용하는 method/property 이름은 기본적으로 다른 top-level(static) method/property 를 가리킴.
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}