Swift Methods
Methods, Instance Methods, Type Methods
1. Methods ๐ฉโ๐ป
Methods
๋ Functions ์ค์์ ํน์ Type ๊ณผ ์ฐ๊ด๋ Functions ๋ฅผ ๋งํ๋ค.
Classes, Structures, Enumerations ๋ชจ๋ Instance ์ ์๋์ ์ํ Instance Methods
๋ฅผ ์ ์ํ๊ณ ,
Encapsulate(์บก์ํ)
ํ ์ ์๋ค. ๋ํ Type
์ ์ํ Type Methods
์ญ์ ์ ์ํ ์ ์๋๋ฐ, ์ด๊ฒ์ Objective-C ์
Class Methods ์ ์ ์ฌํ๋ค.
Objective-C ์์ Classes ๋ Methods ๋ฅผ ์ ์ํ ์ ์๋ ์ ์ผํ ํ์ ์ธ ๋ฐ๋ฉด, Swift ๋ Classes ๋ฟ๋ง ์๋๋ผ Structures ์ Enumerations ์์๋ ์ ์ํ ์ ์๋๋ก ์ ์ฐ์ฑ์ ๋์๋ค.
2. Instance Methods ๐ฉโ๐ป
Instance Methods ๋ Classes, Structures, Enumerations ์ Instance ์ ์ํด ์๋ ํจ์๋ก, Instance ์ Properties ์ ์ ๊ทผ, ์์ ํ๊ฑฐ๋ Instance ์ ์๋์ ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
Instance Methods ๋ ๊ทธ๊ฒ์ด ์ ์๋ context
๋ด์ ๋ค๋ฅธ ๋ชจ๋ Instance Methods ์ Instance Properties ์ ๋ํด
์์์ ์ธ ์ ๊ทผ ๊ถํ
์ ๊ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ Instance Methods ๋ Instance Properties ์ ๋ง์ฐฌ๊ฐ์ง๋ก Instance ์์ด
๋
๋ฆฝ์ ์ผ๋ก ํธ์ถ์ด ๋ถ๊ฐ๋ฅํ๋ค.
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
Counter Class ๋ฅผ ์ ์ํ๊ณ , Counter ํ์
์ counter instance ๋ฅผ ์ ์ธํ๋ค.
Instance Methods ๋ Instance Properties ์ ๋ง์ฐฌ๊ฐ์ง๋ก dot Syntax
๋ฅผ ์ด์ฉํด ํธ์ถํ๋ค.
print(counter.count) // 0
counter.increment()
print(counter.count) // 1
counter.increment(by: 5)
print(counter.count) // 6
counter.reset()
print(counter.count) // 0
1. The self Property
Instance ๋ self
๋ผ๊ณ ๋ถ๋ฆฌ๋ Instance ์๊ธฐ ์์ ๊ณผ ๋์ผํ Property
๋ฅผ ์์์ ์ผ๋ก ๊ฐ๋๋ค(implicit self property).
์๋ Methods ๊ฐ ์๊ธฐ ์์ ์ context ์ธ๋ถ, ์ฆ ์ ๊ฒฝ์ฐ Counter Class ์ context ์ ์ ์๋ Instance Properties ๋ ๋ค๋ฅธ Instance Methods ์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํด์ผํ๋ค.
func increment() {
self.count += 1
}
ํ์ง๋ง Swift ๋ context ๋ด์์ ๋์์ ์ฐพ์ง ๋ชป ํ ๊ฒฝ์ฐ, ํ์ฌ Instance ์ context ์์ ์ฐพ๋๋ก
์์์ ์ผ๋ก self
๋ฅผ ์ฒ๋ฆฌํ๋ฏ๋ก, ๋ช
์์ ์ผ๋ก self
ํค์๋๋ฅผ ๋ถ์ผ ํ์๊ฐ ์๋ค.
func increment() {
count += 1
}
๊ทธ๋ฌ๋ Methods ์ parameters ์ properties ๊ฐ ์ด๋ฆ์ด ์ค๋ณต๋ ๊ฒฝ์ฐ parameters ๊ฐ ์ฐ์ ๊ถ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์์์
self
๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ด ๊ฒฝ์ฐ ๋ช
์์ ์ผ๋ก self
๋ฅผ ์ฒ๋ฆฌํด์ผํ๋ค.
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
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")
}
This point is to the right of the line where x == 1.0
2. Modifying Value Types from Within Instance Methods
Structures ์ Enumerations ๋
Value Types
๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก Value Type ์ Properties ๋ Instance Methods ์ ์ํด ์์ ๋ ์ ์๋ค(immutable).์์ ์ด ํ์ํ ๊ฒฝ์ฐ
mutating
ํค์๋๋ฅผ ์ฌ์ฉํด ์์ ์ ํ์ฉํ๋๋ก ๋ช ์ํด์ผํ๋ค.
mutating Methods ๋ ๋ฉ์๋๊ฐ ์ข ๋ฃ๋ ๋ Properties ๋ฅผ ๋ณ๊ฒฝ
ํ๋ค. ๋ํ ์ด ๋ฉ์๋๋implicit self property
์ ์์ ํnew Instance
๋ฅผ ํ ๋นํ ์๋ ์์ผ๋ฉฐ,'new Instance'๋ ๋ฉ์๋๊ฐ ์ข ๋ฃ๋ ๋ 'original Instance'๋ฅผ ๋์ฒด
ํ๋ค.
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)
print("The point is at (\(somePoint.x), \(somePoint.y))")
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
The point is at (1.0, 1.0)
The point is now at (3.0, 4.0)
mutating
ํค์๋๋ฅผ ์ด์ฉํด Structures ์ Properties ๋ฅผ ์์ ํ๋ ๊ฒ์ Structure Instance ๋ฅผvar
๋ก ์ ์ธํ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํ๋ค.
Stored Properties of Constant Structure Instances
3. Assigning to self Within a Mutating Method
์ 2๋ฒ์์ mutating Methods ๊ฐ Properties ๋ฅผ ๋ณ๊ฒฝํ๋ ์๋ฅผ ๋ณด์๋ค.
์ด๋ฒ์๋ implicit self property
์ ์์ ํ new Instance
๋ฅผ ํ ๋นํด original Instance
๋ฅผ
๋์ฒด ํ๋ ๋ก์ง์ ์ดํด๋ณธ๋ค.
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
mutating func anotherMoveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
anotherMoveBy(x:y:)
๋ self
, ์ฆ, Instance ์๊ธฐ ์์ ์ Point(x:y)
๋ฅผ ์ด์ฉํด ์ Instance ๋ฅผ ์์ฑํ ํ,
๊ธฐ์กด์ Instance ๋ฅผ ๋์ฒดํ๋ค.
var somePoint = Point(x: 1.0, y: 1.0)
print("The point is at (\(somePoint.x), \(somePoint.y))")
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
somePoint.anotherMoveBy(x: 5.0, y: 2.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
The point is at (1.0, 1.0)
The point is now at (3.0, 4.0)
The point is now at (8.0, 6.0)
๊ทธ๋ฆฌ๊ณ ๊ณผ์ฐ ์ด๋ new Instance ๋ฅผ ์ด์ฉํด original Instance ๋ฅผ ๋์ฒดํ๋ฉด somePoint
์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ๋ฐ๋๋์ง๋
ํจ๊ป ํ์ธํด ๋ณด์์ผ๋ ๋ณ๊ฒฝ๋์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
func address(of object: UnsafeRawPointer) -> NSString {
let address = Int(bitPattern: object)
return NSString(format: "%p", address)
}
var somePoint = Point(x: 1.0, y: 1.0)
print("Point's memory address is \(address(of: &somePoint))")
somePoint.moveBy(x: 2.0, y: 3.0)
print("Point's memory address is \(address(of: &somePoint))")
somePoint.anotherMoveBy(x: 5.0, y: 2.0)
print("Point's memory address is \(address(of: &somePoint))")
Point's memory address is 0x10377c840
Point's memory address is 0x10377c840
Point's memory address is 0x10377c840
3. Type Methods ๐ฉโ๐ป
1. Type Method Syntax
Type Property Syntax ์ ๋ง์ฐฌ๊ฐ์ง๋ก Methods ์์ static
ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
struct SomeStructure {
static func someTypeMethod() {
// type method implementation goes here
}
}
Type Methods ์์
self
๋ Instance ๊ฐ ์๋Type itself
, ์ฆType ์์ฒด
๋ฅผ ๊ฐ๋ฆฌํจ๋ค.๊ทธ๋ฆฌ๊ณ Instance Methods ์ ๋ง์ฐฌ๊ฐ์ง๋ก,
self
๋ฅผ ์์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ฏ๋ก Type ์ context ์ ์ ์๋ Type Properties ๋ Type Methods ์ ์ ๊ทผํ๊ธฐ ์ํself
๋ฅผ ์๋ตํ ์ ์๋ค.์ฐจ์ด์ ์ด ์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
Instance Methods
๋context
๋ด๋ถ์ ์ ์๋Instance Properties
์Instance Methods
์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
๋ํ Type Methods ์ ๊ทผ๋ ๊ฐ๋ฅํ๋ฐ,Type ์ full name
์ ๋ถ์ฌ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.Type Methods
๋context
๋ด๋ถ์ ์ ์๋Type Properties
์Type Methods
์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
2. Type Method Examples
๊ฒ์์ ํ๋ ๋ง๋ค์. ์ด ๊ฒ์์๋ ๊ฒ์ ๋ ๋ฒจ์ด ์กด์ฌํ๋ฉฐ, ๊ฒ์์ ๋ ๋ฒจ์ 1์์ ์์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ํ๋ ์ด์ด ์ค ๋๊ตฐ๊ฐ ๊ฒ์์ ๋ ๋ฒจ์ ํด์ ํ๋ฉด ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ์ด ์ฌ๋ผ๊ฐ๊ณ , ๋ชจ๋ ํ๋ ์ด์ด๊ฐ ํด๋น ๋ ๋ฒจ์ ๊ฒ์์ ํ ์ ์๋ค.
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
}
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
- highestUnlockedLevel : ํ๋ ์ด ๊ฐ๋ฅํ ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ.
- currentLevel: ํ์ฌ ๊ฒ์ ๋ ๋ฒจ.
- unlock(_:) : ๋ค์ ๋ ๋ฒจ ๊ฒ์์ ํด์ ํ๋ค. ์ฆ, ํ๋ ์ด ๊ฐ๋ฅํ ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ์ด ์ฌ๋ผ๊ฐ๋ค.
- isUnlocked(to:) : ๊ฒ์ ๋ ๋ฒจ์ด ํด์ ๋์๋์ง ํ์ธํ๋ค.
- advance(to:) : ๊ฒ์ ๋ ๋ฒจ์ ์ฌ๋ฆฐ๋ค.
์ด์ ์ด ๊ฒ์ ๊ท์น์ ์ ์ฉํด ํ๋ ์ด๋ฅผ ์งํํ ๊ฒ์ ํ๋ ์ด์ด๋ฅผ ๋ง๋ ๋ค.
class Player {
var tracker = LevelTracker()
let playerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String) {
playerName = name
}
}
- tracker : ๊ฒ์์ ๊ท์น์ ์ ์ฅํ LevelTracker ๋ฅผ ๋ณ์๋ก ๊ฐ๋๋ค.
complete(level:)
: ํ์ฌ ๋ ๋ฒจ์ ๊ฒ์์ ์๋ฃํ๋ฉด LevelTracker ์unlock(_:)
๋ฉ์๋๋ฅผ ์ด์ฉํด ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ์ ํด์ ํ๊ณ , ํ์ฌ ๊ฒ์ ๋ ๋ฒจ์ ์ฌ๋ฆฐ๋ค.
์ฌ๊ธฐ์ ์ฃผ๋ชฉํด์ผ ํ ์ ์ LevelTracker ๋ Structure ๊ณ , Player ๋ Class ๋ผ๋ ์ ์ด๋ค. ๋ํ ๊ฒ์ ์ค์ ์ LevelTracker ๋ฅผ ๋ณด๋ฉด highestUnlockedLevel ๋ Type Property ๊ณ , currentLevel ์ Instance Property ๋ค.
์ฆ, ์ด๋ค ํ๋ ์ด์ด๊ฐ ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ์ ๋์ฌ ๋์ผ๋ฉด ๊ทธ ๋ค์ ํ๋ ์ด์ด๋ ํด๋น ๋ ๋ฒจ์ ์ ๊ธ์ด ํด์ ๋ ๊ฒ์์ ์ด์ฉํ ์ ์์์ ์๋ฏธํ๋ฉฐ, ์ต๊ณ ๋ ๋ฒจ ํด์ ์ ๋ฌด๊ดํ๊ฒ ์ ํ๋ ์ด์ด๋ ํญ์ ๋ ๋ฒจ 1๋ก ๊ฒ์์ ์์ํด์ผํจ์ ์๋ฏธํ๋ค.
๊ฒ์์ ์งํํด๋ณด์.
var room1 = Player(name: "Harry")
print("\(room1.tracker), Harry is playing level \(room1.tracker.currentLevel).")
LevelTracker(currentLevel: 1), Harry is playing level 1.
ํด๋ฆฌ๊ฐ ํ๋ ์ด์ด๋ฅผ ๋ง๋ค๊ณ 1๋ฒ ๋ฐฉ์์ ๊ฒ์์ ์์ํ๋ค. ํด๋ฆฌ๊ฐ ์งํ์ค์ธ ๊ฒ์ ๋ ๋ฒจ์ 1์ด๋ค.
room1.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
print("\(room1.tracker), Harry is playing level \(room1.tracker.currentLevel).")
highest unlocked level is now 2
LevelTracker(currentLevel: 2), Harry is playing level 2.
ํด๋ฆฌ๊ฐ ๊ฒ์์ ์๋ฃํด ๋ค์ ๋ ๋ฒจ์ ํด์ ํ๋ค.
์ด์ ๊ฒ์์ ์ต๊ณ ๋ ๋ฒจ์ 2๊ณ , ํด๋ฆฌ๋ 1๋ฒ ๋ฐฉ์์ ๋ ๋ฒจ 2๋ฅผ ์งํ์ค์ด๋ค.
var room2 = Player(name: "Ron")
print("\(room2.tracker), Ron is playing level \(room2.tracker.currentLevel).")
LevelTracker(currentLevel: 1), Ron is playing level 1.
๋ก ์ด ์๋ก์ด ํ๋ ์ด์ด๋ฅผ ๋ง๋ค์๋ค. ๋ก ์ ๊ฒ์๋ฐฉ๋ ์๋ก ๋ง๋ค์ด 2๋ฒ๋ฐฉ์์ ๊ฒ์์ ํ๊ธฐ๋ก ํ๋ค.
๊ฒ์ ์ค์ LevelTracker ์ ์ํด ๋ก ์ญ์ ๋ ๋ฒจ 1๋ก ๊ฒ์์ ์์ํ๋ค.
if LevelTracker.isUnlocked(2) {
room2.tracker.advance(to: 2)
}
print("\(room2.tracker), Ron is playing level \(room2.tracker.currentLevel).")
LevelTracker(currentLevel: 2), Ron is playing level 2.
๊ทธ๋ฐ๋ฐ ๋ก ์ ๋ ๋ฒจ 1์ ์ง๋ฃจํ๋ค๋ฉฐ ๋ ๋ฒจ 2๊ฐ ํด์ ๋์๋์ง ํ์ธ ํ, ๋ ๋ฒจ์ ์ฌ๋ฆฌ๊ธฐ๋ก ํ๊ณ ์ฑ๊ณตํ๋ค.
๊ทธ ๊ฒฐ๊ณผ ๋ก ์ 2๋ฒ ๋ฐฉ์์ ๋ ๋ฒจ 2๋ฅผ ์งํ์ค์ด๋ค.
room1 = Player(name: "Hermione")
print("\(room1.tracker), Hermione is playing level \(room1.tracker.currentLevel).")
LevelTracker(currentLevel: 1), Hermione is playing level 1.
์ด๋ฒ์๋ ํค๋ฅด๋ฏธ์จ๋๊ฐ ๊ฒ์์ ์์ํ๋๋ฐ, ํค๋ฅด๋ฏธ์จ๋๋ ํด๋ฆฌ๊ฐ ํ๋ 1๋ฒ๋ฐฉ์์ ๊ฒ์์ ์ด์ด์ ํ๊ธฐ๋ก ํ๊ณ ํ๋ ์ด์ด๋ฅผ ์๋ก ๋ง๋ค์ด ๊ฒ์์ ๋ค์ด๊ฐ๋ค. 1๋ฒ ๋ฐฉ์์ ํด๋ฆฌ๋ ๋ ๋ฒจ 2๋ฅผ ์งํํ๊ณ ์์์ง๋ง ํค๋ฅด๋ฏธ์จ๋๋ ์ ๊ฒ์์ ์์ํ๋ ํ๋ ์ด์ด์ด๋ฏ๋ก ๊ฒ์ ์ค์ LevelTracker ์ ์ํด ๋ง์ฐฌ๊ฐ์ง๋ก ๋ ๋ฒจ 1์์ ์์ํ๋ค.
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
if room1.tracker.advance(to: 6) {
print("Hermione is now on level 6")
} else {
print("level 6 hasn't yet been unlocked")
}
highest unlocked level is now 2
level 6 hasn't yet been unlocked
๊ทธ๋ฐ๋ฐ ํค๋ฅด๋ฏธ์จ๋๋ ๋ฎ์ ๋ ๋ฒจ์ ๊ฒ์์ ์ฌ๋ฏธ ์๋ค๋ฉฐ ํ ๋ฒ์ ๋ ๋ฒจ 6์ผ๋ก ์ฌ๋ฆฌ๊ธฐ๋ฅผ ์ํ๋ค. ํ์ฌ ๊ฒ์ ํ๋ ์ด๊ฐ ๊ฐ๋ฅํ ์ต๊ณ ๋ ๋ฒจ์ด 2๋ผ๋ ๊ฒ์ ํ์ธ ํ์ผ๋ ํน์๋ ํ๋ ๋ง์์ ๋ ๋ฒจ 6์ผ๋ก ์ฌ๋ฆฌ๊ธฐ๋ฅผ ์๋ํ๊ณ , ๋ ๋ฒจ 6์ ์์ง ์ ๊ฒจ์๋ค๋ ๋ฉ์์ง๋ฅผ ๋ฐ์๋ค.
Reference
- โMethods.โ The Swift Programming Language Swift 5.7. accessed Nov. 27, 2022, Swift Docs Chapter 10 - Methods.