์๋ ํ์ธ์. ์ค๋์ Swift ํ๋ก๊ทธ๋๋ฐ์์ ์ค์ํ์ง๋ง ์ข ์ข ๊ฐ๊ณผ๋๋ ๊ฐ๋ ์ธ '๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ(Memory Safety)'์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ์ ์ดํดํ๋ฉด ๋ ์์ ์ ์ด๊ณ ์์ธก ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ, ์ปดํ์ผ ํ์๊ณผ ๋ฐํ์ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๐ Swift์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ์ด๋?
Swift๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๋์์ ๋ฐ์ํ ์ ์๋ ์์ ํ์ง ์์ ๋์์ ๋ฐฉ์งํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
- ๋ณ์๊ฐ ์ฌ์ฉ๋๊ธฐ ์ ์ ์ด๊ธฐํ๋๋์ง ํ์ธ
- ๋ฉ๋ชจ๋ฆฌ๊ฐ ํด์ ๋ ํ์๋ ์ ๊ทผํ์ง ์๋๋ก ๋ณด์ฅ
- ๋ฐฐ์ด ์ธ๋ฑ์ค๊ฐ ๋ฒ์๋ฅผ ๋ฒ์ด๋์ง ์๋์ง ๊ฒ์ฌ
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ์ค์ํ๊ฒ, Swift๋ ๋ฉ๋ชจ๋ฆฌ์ ๋์ผํ ์์น์ ๋ํ ๋ค์ค ์ ๊ทผ์ด ์ถฉ๋ํ์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๊ฒ์ด ์ค๋ ์ค์ ์ ์ผ๋ก ์ดํด๋ณผ ๋ด์ฉ์ ๋๋ค.
๐ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ถฉ๋ ์ดํดํ๊ธฐ
๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ๋ ๊ฒ์ ๋ณ์์ ๊ฐ์ ์ฝ๊ฑฐ๋ ์ธ ๋ ๋ฐ์ํฉ๋๋ค:
// one์ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฐ๊ธฐ ์ ๊ทผ
var one = 1
// one์ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ฝ๊ธฐ ์ ๊ทผ
print("We're number \(one)!")
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ถฉ๋์ ์ฝ๋์ ์๋ก ๋ค๋ฅธ ๋ถ๋ถ์ด ๋์์ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ์ ๊ทผํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด๋ฌํ ์ถฉ๋์ ์์ธกํ ์ ์๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค.
์ค์ํ ๋น์ : ์ข ์ด์ ์ฐ์ฌ์ง ์์ฐํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ณผ์ ์ ์๊ฐํด๋ณด์ธ์. ์ ํญ๋ชฉ์ ์ถ๊ฐํ๋ ๋์ค์๋ ์ด์ก์ด ์ผ์์ ์ผ๋ก ๋ง์ง ์๊ฒ ๋ฉ๋๋ค. ์ด ์์ ์ ๋๊ตฐ๊ฐ ์ด์ก์ ๋ณด๋ฉด ์๋ชป๋ ์ ๋ณด๋ฅผ ์ป๊ฒ ๋ฉ๋๋ค.
๐ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ์ธ ๊ฐ์ง ํน์ฑ
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ถฉ๋์ ์ดํดํ๋ ค๋ฉด ์ธ ๊ฐ์ง ์ฃผ์ ํน์ฑ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค:
- ์ ๊ทผ ์ข ๋ฅ: ์ฝ๊ธฐ ์ ๊ทผ์ธ์ง ์ฐ๊ธฐ ์ ๊ทผ์ธ์ง
- ๋ฉ๋ชจ๋ฆฌ ์์น: ์ด๋ค ๋ณ์, ์์, ๋๋ ํ๋กํผํฐ์ ์ ๊ทผํ๋์ง
- ์ ๊ทผ ๊ธฐ๊ฐ: ์ฆ๊ฐ์ ์ธ(instantaneous) ์ ๊ทผ์ธ์ง ์ฅ๊ธฐ(long-term) ์ ๊ทผ์ธ์ง
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ถฉ๋์ ๋ค์ ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ ๋ ๋ฐ์ํฉ๋๋ค:
- ์ ์ด๋ ํ๋์ ์ ๊ทผ์ด ์ฐ๊ธฐ ์ ๊ทผ์ด๋ค
- ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ์ ๊ทผํ๋ค
- ์ ๊ทผ ๊ธฐ๊ฐ์ด ๊ฒน์น๋ค
์ฆ๊ฐ์ ์ ๊ทผ๊ณผ ์ฅ๊ธฐ ์ ๊ทผ
๋๋ถ๋ถ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ์ฆ๊ฐ์ ์ ๋๋ค. ์ฆ, ์ ๊ทผ์ด ์์๋๊ณ ์๋ฃ๋๋ ์ฌ์ด์ ๋ค๋ฅธ ์ฝ๋๊ฐ ์คํ๋ ์ ์์ต๋๋ค:
func oneMore(than number: Int) -> Int {
return number + 1
}
var myNumber = 1
myNumber = oneMore(than: myNumber)
print(myNumber) // "2" ์ถ๋ ฅ
ํ์ง๋ง ์ฅ๊ธฐ ์ ๊ทผ์ ์ ๊ทผ์ด ์์๋๊ณ ์๋ฃ๋๊ธฐ ์ ์ ๋ค๋ฅธ ์ฝ๋๊ฐ ์คํ๋ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ฅ๊ธฐ ์ ๊ทผ์ ์ฃผ๋ก:
- ํจ์์ ๋ฉ์๋์ in-out ํ๋ผ๋ฏธํฐ
- ๊ตฌ์กฐ์ฒด์ mutating ๋ฉ์๋
์์ ๋ฐ์ํฉ๋๋ค.
๐ in-out ํ๋ผ๋ฏธํฐ์ ์ถฉ๋ ์ ๊ทผ
ํจ์๋ ๋ชจ๋ in-out ํ๋ผ๋ฏธํฐ์ ์ฅ๊ธฐ ์ฐ๊ธฐ ์ ๊ทผ์ ํฉ๋๋ค. ์ด ์ ๊ทผ์ ํจ์ ํธ์ถ์ด ์์๋ ๋ ์์๋์ด ํจ์๊ฐ ๋ฐํ๋ ๋๊น์ง ์ง์๋ฉ๋๋ค.
์์ 1: in-out ํ๋ผ๋ฏธํฐ์ ์ ์ญ ๋ณ์ ์ถฉ๋
var stepSize = 1
func increment(_ number: inout Int) {
number += stepSize // stepSize ์ฝ๊ธฐ
}
increment(&stepSize) // ์ค๋ฅ: stepSize์ ์ถฉ๋ ์ ๊ทผ
์ด ์ฝ๋๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. increment(&stepSize)๋ฅผ ํธ์ถํ๋ฉด:
- stepSize์ ๋ํ ์ฅ๊ธฐ ์ฐ๊ธฐ ์ ๊ทผ์ด ์์๋ฉ๋๋ค(number๊ฐ stepSize๋ฅผ ์ฐธ์กฐ)
- ํจ์ ๋ด๋ถ์์ stepSize์ ๊ฐ์ ์ฝ์ผ๋ ค๊ณ ์๋ํฉ๋๋ค
- ์ด๋ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฝ๊ธฐ์ ์ฐ๊ธฐ ์ ๊ทผ์ด ๊ฒน์ณ ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค
ํด๊ฒฐ์ฑ : ๋ช ์์ ์ธ ๋ณต์ฌ๋ณธ ๋ง๋ค๊ธฐ
// ๋ช
์์ ๋ณต์ฌ๋ณธ ์์ฑ
var copyOfStepSize = stepSize
increment(©OfStepSize)
// ์๋ณธ ์
๋ฐ์ดํธ
stepSize = copyOfStepSize
// stepSize๋ ์ด์ 2์
๋๋ค
์์ 2: ์ฌ๋ฌ in-out ํ๋ผ๋ฏธํฐ ์ถฉ๋
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // OK
balance(&playerOneScore, &playerOneScore)
// ์ค๋ฅ: playerOneScore์ ์ถฉ๋ ์ ๊ทผ
๋์ผํ ๋ณ์๋ฅผ ์ฌ๋ฌ in-out ํ๋ผ๋ฏธํฐ์ ์ ๋ฌํ๋ฉด ๋์ผํ ๋ฉ๋ชจ๋ฆฌ์ ๋ํ ์ฌ๋ฌ ์ฐ๊ธฐ ์ ๊ทผ์ด ๋ฐ์ํ๋ฏ๋ก ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค.
๐ ๋ฉ์๋์์ self์ ๋ํ ์ถฉ๋ ์ ๊ทผ
๊ตฌ์กฐ์ฒด์ mutating ๋ฉ์๋๋ ๋ฉ์๋ ํธ์ถ ๊ธฐ๊ฐ ๋์ self์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ์ ์ํํฉ๋๋ค.
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
์ด ์ํฉ์์๋ ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ต๋๋ค:
extension Player {
mutating func shareHealth(with teammate: inout Player) {
balance(&teammate.health, &health)
}
}
var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria) // OK
oscar.shareHealth(with: &oscar)
// ์ค๋ฅ: oscar์ ์ถฉ๋ ์ ๊ทผ
๋ ๋ฒ์งธ ํธ์ถ์์ ์ถฉ๋์ด ๋ฐ์ํ๋ ์ด์ :
- mutating ๋ฉ์๋๋ self(oscar)์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ์ ์ํํฉ๋๋ค
- in-out ํ๋ผ๋ฏธํฐ teammate๋ ๋์ผํ oscar ์ธ์คํด์ค์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ์ ์ํํฉ๋๋ค
- ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ๋ ์ฐ๊ธฐ ์ ๊ทผ์ด ๊ฒน์ณ ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค
๐ ํ๋กํผํฐ์ ๋ํ ์ถฉ๋ ์ ๊ทผ
๊ฐ ํ์ (๊ตฌ์กฐ์ฒด, ํํ, ์ด๊ฑฐํ)์์๋ ๊ฐ์ ์ผ๋ถ๋ถ์ ๋ณ๊ฒฝํ๋ฉด ์ ์ฒด ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ด๋ ํน์ ํ๋กํผํฐ์ ์ ๊ทผํ๋ฉด ์ ์ฒด ๊ฐ์ ์ ๊ทผํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// ์ค๋ฅ: playerInformation์ ํ๋กํผํฐ์ ์ถฉ๋ ์ ๊ทผ
var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy) // ์ค๋ฅ
๊ทธ๋ฌ๋ ์ปดํ์ผ๋ฌ๊ฐ ์์ ์ฑ์ ์ฆ๋ช ํ ์ ์๋ค๋ฉด ์ ๊ทผ์ ํ์ฉํฉ๋๋ค:
func someFunction() {
var oscar = Player(name: "Oscar", health: 10, energy: 10)
balance(&oscar.health, &oscar.energy) // OK
}
์ ์์ ์์๋ ๋ค์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋์ด ์์ ํ ์ ๊ทผ์ผ๋ก ํ๋จ๋ฉ๋๋ค:
- ์ธ์คํด์ค์ ์ ์ฅ ํ๋กํผํฐ๋ง ์ ๊ทผํจ(๊ณ์ฐ ํ๋กํผํฐ๋ ํด๋์ค ํ๋กํผํฐ ์๋)
- ๊ตฌ์กฐ์ฒด๊ฐ ์ง์ญ ๋ณ์์ ๊ฐ์(์ ์ญ ๋ณ์ ์๋)
- ๊ตฌ์กฐ์ฒด๊ฐ ํด๋ก์ ์ ์บก์ฒ๋์ง ์๊ฑฐ๋ non-escaping ํด๋ก์ ์๋ง ์บก์ฒ๋จ
๐ ์์ ํ ์ฝ๋ ์์ฑ์ ์ํ ํ
๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ์ถฉ๋์ ํผํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ์ง์นจ:
- ๋ณ์์ ๋ฒ์ ์ ํํ๊ธฐ: ์ ์ญ ๋ณ์๋ณด๋ค ์ง์ญ ๋ณ์๋ฅผ ์ ํธํ์ธ์
- ๋ช ์์ ์ธ ๋ณต์ฌ๋ณธ ์ฌ์ฉํ๊ธฐ: ๋์ผํ ๋ณ์์ ์ฌ๋ฌ ๋ฒ ์ ๊ทผํด์ผ ํ ๋๋ ๋ณต์ฌ๋ณธ์ ๋ง๋์ธ์
- in-out ํ๋ผ๋ฏธํฐ ์ฌ์ฉ ์ ์ฃผ์ํ๊ธฐ: ๋์ผํ ๋ณ์๋ฅผ ์ฌ๋ฌ in-out ํ๋ผ๋ฏธํฐ์ ์ ๋ฌํ์ง ๋ง์ธ์
- ๊ฐ ํ์ ์ ํ๋กํผํฐ์ ๋ํ ๋์ ์ ๊ทผ ํผํ๊ธฐ: ํนํ ์ ์ญ ๋ณ์๋ escaping ํด๋ก์ ์ ํจ๊ป ์ฌ์ฉํ ๋ ์ฃผ์ํ์ธ์
- mutating ๋ฉ์๋ ๋ด์์ self์ ๋ํ ์ฐธ์กฐ ์ฃผ์ํ๊ธฐ: ํนํ ๋ค๋ฅธ ์ธ์คํด์ค์ ์ํธ์์ฉํ ๋ ํ์ธํ์ธ์
๐ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ๊ณผ ์ฑ๋ฅ ์ฌ์ด์ ๊ท ํ
Swift์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๊ท์น์ ์ฝ๋์ ์์ ์ฑ์ ๋์ด์ง๋ง, ๋๋ก๋ ๊ณผ๋ํ๊ฒ ์ ํ์ ์ผ๋ก ๋๊ปด์ง ์ ์์ต๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ์ ์ฆ๋ช ํ ์ ์๋ ๊ฒฝ์ฐ์๋ ์ค์ ๋ก๋ ์์ ํ ์ฝ๋๊ฐ ์์ ์ ์์ต๋๋ค.
Swift์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๊ฐ์ ๋ ์ ์ถฉ์์ ๋๋ค:
- ๋ฉ๋ชจ๋ฆฌ ๋ฐฐํ์ ์ ๊ทผ(exclusive access): ๋ ์๊ฒฉํ ์๊ตฌ์ฌํญ
- ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ(memory safety): ๋ฐฐํ์ ์ ๊ทผ๋ณด๋ค ๋ ์๊ฒฉํจ
์ปดํ์ผ๋ฌ๊ฐ ์์ ํ๋ค๊ณ ์ฆ๋ช ํ ์ ์๋ ๊ฒฝ์ฐ์๋ ๋ ์ ์ฐํ ์ ๊ทผ์ ํ์ฉํฉ๋๋ค. ์ด๋ฌํ ๊ท ํ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ปดํ์ผ๋ฌ๊ฐ ๋ ๋ง์ ํจํด์ ์์ ํ๋ค๊ณ ์ธ์ํ๋ฉด์ ๊ณ์ ๋ฐ์ ํ ๊ฒ์ ๋๋ค.
๐ ์ ๋ฆฌ
Swift์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๋ฉ์ปค๋์ฆ์ ์ฝ๋์ ์์ ์ฑ๊ณผ ์์ธก ๊ฐ๋ฅ์ฑ์ ๋์ด๋ ์ค์ํ ๊ธฐ๋ฅ์ ๋๋ค. ์ฃผ์ ๊ฐ๋ ์ ์ ๋ฆฌํ๋ฉด:
- ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ถฉ๋์ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ๋์ ์ ๊ทผ์์ ๋ฐ์ํฉ๋๋ค
- ์ถฉ๋์ด ๋ฐ์ํ๋ ค๋ฉด ์ ์ด๋ ํ๋์ ์ฐ๊ธฐ ์ ๊ทผ์ด ์์ด์ผ ํ๋ฉฐ, ๋์ผํ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ๊ณ , ์ ๊ทผ ๊ธฐ๊ฐ์ด ๊ฒน์ณ์ผ ํฉ๋๋ค
- ์ฅ๊ธฐ ์ ๊ทผ์ ์ฃผ๋ก in-out ํ๋ผ๋ฏธํฐ์ mutating ๋ฉ์๋์์ ๋ฐ์ํฉ๋๋ค
- ๊ฐ ํ์ ์ ํ๋กํผํฐ ์ ๊ทผ์ ์ ์ฒด ๊ฐ์ ๋ํ ์ ๊ทผ์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค
- ์ปดํ์ผ๋ฌ๊ฐ ์์ ํ๋ค๊ณ ์ฆ๋ช ํ ์ ์๋ ๊ฒฝ์ฐ์๋ ๋ ์ ์ฐํ ์ ๊ทผ์ด ํ์ฉ๋ฉ๋๋ค
'๐ฅ Bread Basics > Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๊ณ ๊ธ ์ฐ์ฐ์ (Advanced Operators) (1) | 2025.04.13 |
---|---|
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์ ๊ทผ ์ ์ด (Access Control) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์๋ ์ฐธ์กฐ ์นด์ดํ (Automatic Reference Counting) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ๋ถํฌ๋ช ํ ํ์ (Opaque Types) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์ ๋๋ฆญ (Generics) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ํ๋กํ ์ฝ (Protocols) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ํ์ฅ (Extensions) (0) | 2025.04.13 |
Swift ๊ณต์ ๋ฌธ์ ์ ๋ฆฌ - ์ค์ฒฉ๋ ํ์ (Nested Types) (1) | 2025.04.12 |