Struct vs Class
Struct ํ์ ๊ณผ Class ํ์ ์ ๋น๊ตํ ๋ ๊ฐ์ฅ ๋ง์ด ํ๋ ๋ง โ Struct๋ ๊ฐ ํ์ , Class๋ ์ฐธ์กฐ ํ์ !
- ๊ฐ ํ์ : ์ ๋ฌํ ๋๋ง๋ค ๊ฐ์ ๋ณต์ฌํด์ ์ ๋ฌ
- ์ฐธ์กฐ ํ์
: ํ๋์ ์ธ์คํด์ค๊ฐ ์ฐธ์กฐ๋ฅผ ํตํด ์ฌ๋ฌ ๊ณณ์์ ์ ๊ทผ
- ์ธ์คํด์ค๊ฐ ์ ์ ํ ์์ ์ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์์์ ๋ญ๋นํ๊ฒ ๋จ.
โ ์ค์ํํธ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ๊ด๋ฆฌํ๊ธฐ ์ํด ARC๋ฅผ ์ฌ์ฉ!
ARC์ ์๋ ๊ท์น์ ๋ชจ๋ฅด๊ณ ์ฌ์ฉํ๋ฉด ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์์ํ ํด์ ๋์ง ์์ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์... ARC์ ๋ํด ์์์ผ ํ๋ค.
ARC
* ์๋ ์ฐธ์กฐ ์นด์ดํ , Automatic Reference Counting => ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌํด ์ฃผ๋ ๋ฐฉ์
* ๋ ์ด์ ํ์ํ์ง ์์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ์ํด
-> ๋ ์ด์ ํ์ํ์ง ์์ ํด๋์ค๋ฅผ ํ๋จํ๊ธฐ ์ํด ์ฐธ์กฐ ํ์๋ฅผ ์นด์ดํธ!
* RC(Reference Counting)๊ฐ 0์ด ๋๋ ์๊ฐ ์ธ์คํด์ค๋ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋จ
* ์ธ์คํด์ค๊ฐ ๊ณ์ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์์ด์ผ ํ ๋ฌด์ธ๊ฐ ๋ช ๋ถ์ด ํ์ํ๋ค! โ ๊ฐํ(Strong) ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ RC๋ฅผ 1 ์ฆ๊ฐ์ํด
๊ฐํ ์ฐธ์กฐ
ํด๋์ค์ ํ๋กํผํฐ ๋ฑ์ ์ ์ธํ ๋ ๋ฑํ ๋ฌด์์ธ๊ฐ๋ฅผ ๋ช ์ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ์ผ๋ก ๊ฐํ ์ฐธ์กฐ
// ์ด ์ฝ๋์์ ๋งํ๋ RC(Reference Counting)๋ Person ํด๋์ค์ ์ธ์คํด์ค RC!!!
class Person {
let name: String
init(name: String) {
self.name = name
}
}
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "JUNGBIN") // RC = 1
reference2 = reference1 // RC = 2
reference3 = reference1 // RC = 3
reference3 = nil // RC = 2
reference2 = nil // RC = 1
reference1 = nil // RC = 0 -> ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋จ!!!!
๊ฐํ ์ฐธ์กฐ ์ํ ๋ฌธ์
* ๋ ์ธ์คํด์ค๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํ๋ ์ํฉ์์ ๊ฐํ ์ฐธ์กฐ ์ํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
class Person {
let name: String
init(name: String) {
self.name = name
}
var car: Car?
}
class Car {
let name: String
init(name: String) {
self.name = name
}
var owner: Person?
}
var jungbin: Person? = Person(name: "JUNGBIN") // Person RC = 1
var myCar: Car? = Car(name: "BoongBoong") // Car RC = 1
myCar?.owner = jungbin // Person RC = 2
jungbin?.car = myCar // Car RC = 2
jungbin = nil // Person RC = 1
myCar = nil // Car RC = 1
* ์ ์ฝ๋์์, jungbin์ nil์ ํ ๋นํ์ ๋ Person RC = 1์ด ๋จ. jungbin์ ์ด์ nil์ด์ง๋ง, myCar.owner๋ฅผ ํตํด ์์ง Person ์ธ์คํด์ค์ ์ฐธ์กฐํ ์ ์์. Person ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ด์ ์๊ณ , Person ์ธ์คํด์ค์ ์ฐธ์กฐํ ๋ฐฉ๋ฒ๋ ๋จ์ ์๋ ์ํฉ! ํ์ง๋ง ๋ค์์ myCar์ nil์ ํ ๋นํ์ ๋, myCar๊ฐ ์ฐธ์กฐํ๋ ์ธ์คํด์ค์ RC๋ ํ๋ ๊ฐ์ํ์ฌ 1์ด ๋์์. ๊ทผ๋ฐ ์ด์ myCar.owner๋ก Person ์ธ์คํด์ค์ ์ ๊ทผํ์ง ๋ชปํ๊ณ , myCar๋ nil์ด๋ผ์ Car ์ธ์คํด์ค์ ์ ๊ทผํ์ง ๋ชปํจ. ์ธ์คํด์ค์ ์ ๊ทผํ ๋ฐฉ๋ฒ์ ์ฌ๋ผ์ก๋๋ฐ, ์ ์ ์ธ์คํด์ค๋ค์ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์๊ธฐ ๋๋ฌธ์(RC = 1) ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์!
* ์๋ ๊ทธ๋ฆผ์์ ViewController๊ฐ ํ๋ฉด์์ pop ๋๊ณ ์ด์ ์ฌ์ฉํ์ง ์๋๋ฐ๋ ๋ถ๊ตฌํ๊ณ 3๋ฒ์ self.์ด์ฉ๊ณ ์ ์ฉ๊ณ ์ฝ๋์ ์ํด RC ์นด์ดํธ๊ฐ ํ ๋ฒ ์ฆ๊ฐ๋์๊ธฐ ๋๋ฌธ์ 4๋ฒ์์ RC = 1์ด ๋จ. ViewController์ ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋์ง ์์!!!! โ ๋ฉ๋ชจ๋ฆฌ ๋์(Memory Leak)

์ฝํ ์ฐธ์กฐ
* ๊ฐํ ์ฐธ์กฐ์ ๋ฌ๋ฆฌ, ์์ ์ด ์ฐธ์กฐํ๋ ์ธ์คํด์ค์ ์ฐธ์กฐ ํ์๋ฅผ ์ฆ๊ฐ์ํค์ง ์์
* ์ฐธ์กฐํ๋ ํ์ ์ ํ๋กํผํฐ๋ฅผ ์ ์ธํ๋ ๋ฌธ์ฅ ์์ weak๋ฅผ ์จ ์ฃผ๋ฉด ๊ทธ ํ๋กํผํฐ๋ ์ธ์คํด์ค๋ฅผ ์ฝํ ์ฐธ์กฐ!
* ์๋ ์ฝ๋๋ ์ฝํ ์ฐธ์กฐ๋ฅผ ํตํด ๊ฐํ ์ฐธ์กฐ ์ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ฝ๋
class Person {
let name: String
init(name: String) {
self.name = name
}
var car: Car?
}
class Car {
let name: String
init(name: String) {
self.name = name
}
weak var owner: Person?
}
var jungbin: Person? = Person(name: "JUNGBIN") // Person RC = 1
var myCar: Car? = Car(name: "BoongBoong") // Car RC = 1
myCar?.owner = jungbin // Person RC = 1 ์ฝํ ์ฐธ์กฐ!
jungbin?.car = myCar // Car RC = 2 ๊ฐํ ์ฐธ์กฐ!
jungbin = nil // Person RC = 0, Car RC = 1
print(myCar?.owner) // Person์ ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์๊ธฐ ๋๋ฌธ์ nil(์ฝํ ์ฐธ์กฐ ํด์ ๊ทธ๋ผ)
myCar = nil // Car RC = 0
* ์๋์์ ์ธ ๋ฒ์งธ ๋ผ์ธ์ ๋ณด๋ฉด... ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋ ๋, ์์ ์ ํ๋กํผํฐ(car)๊ฐ ๊ฐํ ์ฐธ์กฐ๋ฅผ ํ๋ ์ธ์คํด์ค(Car ์ธ์คํด์ค)์ RC๋ฅผ 1 ๊ฐ์์ํจ๋ค๋ ๊ฒ์ ์ ์ ์์
๊ฐํ ์ฐธ์กฐ ์ํ ๋ฌธ์ ๋ฅผ ๋ฉ์ง๊ฒ ํด๊ฒฐํ์์ต๋๋ค~~~