์ƒ์„ธ ์ปจํ…์ธ 

๋ณธ๋ฌธ ์ œ๋ชฉ

[ Swift ] ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ(ARC)

๐ŸŽ iOS/Swift

by AHN.Jihyeon 2024. 7. 13. 12:12

๋ณธ๋ฌธ

๐ŸŒŸ ๋ฉ”๋ชจ๋ฆฌ์™€ ๋””์Šคํฌ

๋ฉ”๋ชจ๋ฆฌ ๋””์Šคํฌ
์ผ๋ฐ˜์ ์œผ๋กœ RAM์„ ๋งํ•จ(๋ช‡ GB)

RAM์€ ํœ˜๋ฐœ์„ฑ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅ โŒ
→ ์•ฑ ์‹คํ–‰ ์ค‘ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์•ฑ์„ ์ข…๋ฃŒ ์‹œ ์‚ญ์ œ
→ ์•ฑ ์‹คํ–‰์„ ์‹œํ‚ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ„๋‹ค.
→ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์•ฑ์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋‚ด๋ ค์˜ฌ ๋•Œ ๊ฐ™์ด ๋‚ด๋ ค์˜ด
→ RAM ์˜ ์šฉ๋Ÿ‰์ด ํด ์ˆ˜๋ก, ๋™์‹œ์— ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์•ฑ์˜ ์ด๋Ÿ‰ ๋งŽ์Œ

๋””์Šคํฌ๋ณด๋‹ค ์†๋„๊ฐ€ ๋น ๋ฆ„ (CPU๊ฐ€ ๋””์Šคํฌ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ์— ๋” ๋นจ๋ฆฌ ์ ‘๊ทผ)

๋””์Šคํฌ์— ๋น„ํ•ด ์šฉ๋Ÿ‰์ด ์ž‘์Œ (๋ณดํ†ต 8GB, 16GB, 32GB)

EEPROM
๊ณผ ๊ฐ™์€ ๋น„ํœ˜๋ฐœ์„ฑ ๋ฉ”๋ชจ๋ฆฌ๋„ ์žˆ์Œ 
์•„์ดํฐ์€ ์ด๊ณณ์— ์žฅ์น˜์˜ ์ผ๋ จ๋ฒˆํ˜ธ ๋ฐ ํ•˜๋“œ์›จ์–ด ์ •๋ณด๋ฅผ ์ €์žฅ



์˜๊ตฌ์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณณ. ๋น„ํœ˜๋ฐœ์„ฑ ์žฅ์น˜
→ ์•ฑ ์‹คํ–‰ ์ค‘ ์•ฑ์„ ์ข…๋ฃŒํ•ด๋„ ๋””์Šคํฌ์— ์žˆ์Œ



ํŒŒ์ผ, ๋ฌธ์„œ, ํ”„๋กœ๊ทธ๋žจ ๋“ฑ ์ƒ๋Œ€์ ์œผ๋กœ ์šฉ๋Ÿ‰์ด ํฐ ์ •๋ณด๋“ค์„ ๋‹ด์„ ์ˆ˜ ์žˆ์Œ

๋ฉ”๋ชจ๋ฆฌ์— ๋น„ํ•ด ์†๋„๊ฐ€ ๋Š๋ฆผ



UserDefaults, CoreData๋ฅผ ํ™œ์šฉํ•ด ๋””์Šคํฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ

 

 

 

 

๐ŸŒŸ MRC(Manual Reference Counting)์™€ ARC(Automatic Reference Counting)

ARC(Automatic Reference Counting) MRC(Manual Reference Counting)
ARC๋Š” Swift ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ.
Java ์— GC ๊ฐ€ ์žˆ๋‹ค๋ฉด Swift ์—๋Š” ARC ๊ฐ€ ์žˆ์Œ.

Reference Count ๋ฅผ ์ž๋™์œผ๋กœ ๊ณ„์‚ฐ. (Automatic)
๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ RC = 1
๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋‚˜ ์†์„ฑ์— ํ• ๋‹น๋˜์–ด ์ฐธ์กฐ๋ ๋•Œ๋งˆ๋‹ค RC +1
๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํ•ด์ œ๋ ๋•Œ๋งˆ๋‹ค RC -1
RC = 0 ์ด๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ
MRC ๋Š” Objective-C ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ


Reference Count ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋กœ ์ง์ ‘ ๊ณ„์‚ฐ. (Manual)
๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ ๋•Œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น
๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋‚˜ ์†์„ฑ์— ํ• ๋‹น๋˜์–ด ์ฐธ์กฐ๋ ๋•Œ๋งˆ๋‹ค ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ RC ์ฆ๊ฐ€
๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํ•ด์ œ๋ ๋•Œ๋งˆ๋‹ค ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ RC ๊ฐ์†Œ
RC ๊ฐ€ 0 ์ด๋˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ.

 

 

์˜ˆ์‹œ 

class MyClass {
	init(){}
    
    deinit{} // ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋  ๋•Œ ํ˜ธ์ถœ
}

// myClass์— ๋Œ€ํ•œ RC = 1   :  : MyClass ์ƒ์„ฑ. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น๋ฐ›์Œ
var myClass: MyClass? = MyClass() 


// RC = 2 : myClass2๊ฐ€ myClass๋ฅผ ์ฐธ์กฐ
var myClass2 = myClass

// RC = 2 -1 = 1
myClass = nil


// RC = 1 -1 = 0  : MyClass ์†Œ๋ฉธ
myClass2 = nil

์ธ์Šคํ„ด์Šค๋ฅผ ์„ ์–ธํ•จ์œผ๋กœ์จ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ๋‹ค. 

๋ฉ”๋ชจ๋ฆฌ๋ผ๋Š” ๊ณต๊ฐ„์— MyClass๊ฐ€ ์˜ฌ๋ผ๊ฐ„ ๊ฒƒ์ด๋‹ค.

 

์ธ์Šคํ„ด์Šค๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ฐธ์กฐ์ž(์†Œ์œ ์ž)๊ฐ€ ์žˆ์–ด์•ผ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€๊ฐ€ ๋œ๋‹ค.

์ฐธ์กฐ์ž๊ฐ€ ์—†๋‹ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ œ๊ฑฐ๊ฐ€ ๋˜๊ณ , ์ด๋•Œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ฐธ์กฐ์ž์˜ ๊ฐœ์ˆ˜๋ฅผ RC๋ผ ํ•œ๋‹ค. 

RC = 0 ์ด๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ญ์ œ. 

 

 

 

 

๐ŸŒŸ ์•ฝ์ฐธ์กฐ์™€ ๊ฐ•์ฐธ์กฐ

์•ฝ์ฐธ์กฐ - weak ํ‚ค์›Œ๋“œ 

Reference Count ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š์œผ๋ฉด์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ.

 

๊ฐ•์ฐธ์กฐ - ์ผ๋ฐ˜์ ์ธ ์ฐธ์กฐ ๋ฐฉ์‹

Reference Count ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ.

 

 

 

๐ŸŒŸ ํด๋กœ์ €์˜ ์บก์ฒ˜๋ง / ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ 

Swift์—์„œ ํด๋กœ์ € ์•ˆ์—์„œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ์บก์ฒ˜๋ง์ด ์žˆ๋‹ค. 

class Jihyeon {
    let mbti = "ENFP"
    init() {
        print("ํด๋ž˜์Šค ์ƒ์„ฑ")
    }
    deinit {
        print("ํด๋ž˜์Šค ์†Œ๋ฉธ")
    }
}

// jh rc = 1
var jh: Jihyeon? = Jihyeon()

// ํด๋กœ์ € ๋‚ด๋ถ€์—์„œ jh ์บก์ฒ˜ํ•˜๋ฉด rc +1 ์ฆ๊ฐ€. jh rc = 2
let printMbti: () -> () = { [jh] in   //์บก์ฒ˜๋ง -> ํด๋กœ์ €์—์„œ ์™ธ๋ถ€์˜ ๊ฐ’ ์บก์ฒ˜ํ•ด์„œ ์‚ฌ์šฉ ์‹œ RC ์ฆ๊ฐ€
    guard let jh else { return }      //guard let์œผ๋กœ ์˜ต์…”๋„๋ฐ”์ธ๋”ฉ
    print("jihyeon's mbti = \(jh.mbti)")
}

printMbti()

// jh rc = 2-1 = 1  
jh = nil


// ์œ„์˜ 15๋ฒˆ ์ฝ”๋“œ์—์„œ weak ํ‚ค์›Œ๋“œ๋ฅผ ์ผ๋‹ค๋ฉด, jh rc = 1
// let printMbti: () -> () = { [weak jh] in 
// jh = nil   -> ํด๋ž˜์Šค ์†Œ๋ช…

 

๊ฐ’ํƒ€์ž…์˜ ์บก์ฒ˜๋Š” ํด๋กœ์ € ๋‚ด๋ถ€์—์„œ ์™ธ๋ถ€์˜ ๋ณ€์ˆ˜๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•ด์•ผํ•ด์„œ ์บก์ฒ˜ 

๊ฐ’ํƒ€์ž…์˜ [์บก์ฒ˜๋ฆฌ์ŠคํŠธ]๋Š” ํด๋กœ์ € ์™ธ๋ถ€์— ์กด์žฌํ•˜๋Š” ๊ฐ’์„ ๋ณต์‚ฌํ•ด์„œ ์‚ฌ์šฉ. ์™ธ๋ถ€ ์š”์ธ์— ์˜ํ•œ ๊ฐ’ ๋ณ€๊ฒฝ ๋ฐฉ์ง€

 

 

๐ŸŒŸ ์ˆœํ™˜ ์ฐธ์กฐ(๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด) 

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(Memory Leak) : ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์Œ“์—ฌ ๋ฉ”๋ชจ๋ฆฌ์— ๋ถ€๋‹ด์ด ๋˜๋Š” ์ƒํ™ฉ

 

ํด๋ž˜์Šค A๊ฐ€ ํด๋ž˜์ŠคB๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ƒํ™ฉ์ด๋‹ค. 

์ˆœํ™˜์ฐธ์กฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€์ด๋‹ค. 

class Person {
    var pet: Dog?
    init() {
        print("Person ํด๋ž˜์Šค ์ƒ์„ฑ")
    }
    deinit {
        print("Person ํด๋ž˜์Šค ์†Œ๋ฉธ")
    }
}

class Dog {
    var owner: Person?
    init() {
        print("Dog ํด๋ž˜์Šค ์ƒ์„ฑ")
    }
    deinit {
        print("Dog ํด๋ž˜์Šค ์†Œ๋ฉธ")
    }
}


// person rc = 1
var person: Person? = Person()

// dog rc = 1
var dog: Dog? = Dog()


// dog rc = 2 : dog์˜ ์†Œ์œ ์ž(์ฐธ์กฐ์ž)๊ฐ€ ์ฆ๊ฐ€
person?.pet = dog

// person rc = 2
dog?.owner = person


// person rc = 1
person = nil

// dog rc = 1
dog = nil

 

 

 

๊ด€๋ จ๊ธ€ ๋”๋ณด๊ธฐ