์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- ios
- ์ง๋ฒ๋ณํ
- ์๊ณ ๋ฆฌ์ฆ
- String.Index
- CRUD
- ์ฑ๋ง๋ค๊ธฐ
- mongoose
- Encodable
- Firestore
- ์ฑ๋์์ธ
- SWiFT
- Mac
- Core Data
- RxSwift
- Reduce
- Codable
- ํ๋ก๊ทธ๋๋จธ์ค
- Decodable
- nodejs
- MongoDB
- Cloud Firestore
- AVAudioPlayer
- UIRefreshController
- ExpressJS
- Figma
- Filter
- DispatchQueue
- Firestore CRUD
- map
- components
- Today
- Total
Focus On Develop ๐ค๐ค
[Swift] strong, weak, unowned ๋ณธ๋ฌธ
๋จผ์ ARC์ ๊ฐ๋ ์ ๋ํด์ ์ง๊ณ ๋์ด์์ผ ์์ฐ์ค๋ฝ๊ฒ ๋ฉ๋ชจ๋ฆฌ ๋์์ ๋ํ ์ด์ผ๊ธฐ๊ฐ ๋ ๊ฒ ๊ฐ์ต๋๋ค ๐
๐ 2021/01/29 - [iOS [Swift]] - [Swift] ARC (Automatic Reference Counting)
์ ๊น ์์ฝํ๋ฉด
ARC๋ Swift์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํด์ค๋ค๋ ๊ฐ๋ ์ธ๋ฐ, ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ฃผ์ง๋ง ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋ ํฌ์ธํธ๊ฐ ์์์ฃ . ๊ทธ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋ ํฌ์ธํธ๋ ์ธ์ ์ด๋ฉฐ, ์ด๋ป๊ฒ ๋ฐฉ์ง๋ฅผ ํด์ผ ํ ์ง์ ๋ํด์ ์์๋ณด๋ ค ํฉ๋๋ค.
** ์ฌ๊ธฐ์๋ถํฐ๋ Swift ๊ณต์ Document๋ฅผ ์ฐธ๊ณ ํด์ ์์ฑํ์ต๋๋ค **
[Swift Docs] docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
Automatic Reference Counting — The Swift Programming Language (Swift 5.3)
Automatic Reference Counting Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yours
docs.swift.org
ARC ์ ๋ฆฌ๋ฅผ ํ๋ฉด์ Object๋ฅผ ์ฐธ์กฐํ๋ค๋ ๊ฑด ์ด์ ์๊ฒ ๋๋ฐ, ์ฐธ์กฐ์ ๋ฐฉ๋ฒ๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ด์.
string (๊ฐํ) / weak(์ฝํ) / unowned(๋ฏธ์์ ) 3๊ฐ์ง Reference Cycles (์ฐธ์กฐ ์ํ) ์ด ์กด์ฌํฉ๋๋ค.
๋จผ์ string reference cycle(๊ฐํ ์ฐธ์กฐ ์ํ)์ ์๋์ ๊ฐ์ด ๋ฐ์ํฉ๋๋ค.
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
์์ ๊ฐ์ด Person , Apartment ํด๋์ค๊ฐ ์์๋
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
๊ฐ๊ฐ Object๋ฅผ ๋ง๋ค์ด john, number73 ์ด๋ผ๋ ๋ณ์์ ํ ๋นํด์. ( = john, number73 ๊ฐ ์๋ก ๋ง๋ Object๋ฅผ ์ฐธ์กฐํ๋ค๋ ์๋ฏธ)
์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ณ์๊ฐ Object๋ฅผ ์ฐธ์กฐํ๋ ๋ฐฉ์์ด strong ์ฐธ์กฐ์ ๋๋ค. john๊ณผ number73์ ๊ฐ๊ฐ Object์ ๋ํด ๊ฐํ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์.
john์ apartment์ number73์ tenant๊ฐ ๊ฐ๊ฐ nil์ด์ฌ์, ์ง๊ธ ์ํ๋ก๋ john๊ณผ number73์ ์ ํ ์๋ก๋ฅผ ์ฐธ์กฐํ์ง ์์ต๋๋ค.
john = nil
number73 = nil
์ด๋ ๊ฒ nil์ ๊ฐ๊ฐ ํ ๋นํด์ฃผ๋ฉด, deinit์ด ํธ์ถ๋์ด ๋ฉ๋ชจ๋ฆฌ ์์์ Reference Count(์ฐธ์กฐ๊ณ์)๊ฐ 0์ด๋๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์์ ธ์.
๊ทธ๋ฐ๋ฐ ์ด๋ฐ ๊ฒฝ์ฐ๋ ์ด๋จ๊น์?
john!.apartment = number73
number73!.tenant = john
๊ทธ๋ ๋ค.. ์ด์ ๋ john์ apartment์ Apartment์ tenant๋ฅผ ํ ๋นํด์ค์ผ๋ก์จ, ์๋์ ๊ฐ์ด ์๋ก ๊ฐํ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ๋์.
์ด๋ฐ ์ํ์์ ๋ค์ john๊ณผ number73์ nil๋ก ํ ๋นํ๋ฉด
john = nil
number73 = nil
๋ ์ด์ john๊ณผ number73๋ Object๋ฅผ ์ฐธ์กฐํ์ง ์์์. ๋ค๋ง ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด, Object๋ผ๋ฆฌ ์๋ก ๊ฐํ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ด์ Reference Count(์ฐธ์กฐ๊ณ์)๋ฅผ Object ๊ฐ๊ฐ 1์ฉ ๊ฐ์ง๊ณ ์๊ฒ ๋์ฃ ? ๊ทธ์ ๋ฐ๋ผ Garbage Collector๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ด ๋๊ฐ์ Object๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ ๊ฐ์ฃผํ๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ฐ์ง ์๊ณ ๋จ๊ฒจ๋ก๋๋ค..๐
๋ฐ๋ก ์ด ํฌ์ธํธ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์๋๋ ์ง์ ์ ๋๋ค..!!!
์ด์ ์ Object ๋๊ฐ๋ ์์ ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ๋ผ์ง์ง ์์๊บผ์ผ.. ๐ญ๐ญ
์ด๋ฐ ๊ฐ๋ ฅ ์ฐธ์กฐ ์ํ์ ์ฌ์ฉํ ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ญ๋น๋๋ ํฌ์ธํธ์ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ์์ผ๋ก 2๊ฐ์ง๊ฐ ์์ด์.
๋ฐ๋ก.. ์์์ ์ธ๊ธํ๋ "์ฝํ ์ฐธ์กฐ ์ํ"๊ณผ "๋ฏธ์์ ์ฐธ์กฐ ์ํ" ์ด์์.
๋จผ์ weak Reference Cycle(์ฝํ ์ฐธ์กฐ ์ํ)์ Object ๋ผ๋ฆฌ ์ฐธ์กฐํ ๋ ์ฝํ ์ฐธ์กฐ๋ฅผ ํ๋๋ก ํด์, Reference Count๋ฅผ ์ฆ๊ฐ์ํค์ง ์๋๋ก ํฉ๋๋ค. ์ฆ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ฉ๊ทธ๋ฌ๋ ๋จ์์๋ Object๋ฅผ ์ฐธ์กฐํ ๋, ๋ ์ด์ ์ฐธ์กฐํ์ง ์๋๋ก ์ฐธ์กฐ๋ฅผ ๊นจ๋ฒ๋ฆฌ๊ฒ ๋๋๊ฑฐ์ฃ !
์ฝํ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ weakํค์๋๋ฅผ ์์ ์ฌ์ฉํด์ค๋๋ค. weak์ผ๋ก ์ ์ธํ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ nil์ผ ์ ์์ด์, ๋ฐ๋์ Optional๋ก ์ ์ธ๋์ด nil์ด ํ ๋น๋ ์ ์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด์์. ๋ฌผ๋ก ์ค์ ๋ก weak์ ์ฌ์ฉํ ๋๋ unwrapping์ ์ ๊ฑฐ์ณ์ ์์ ํ๊ฒ ์ฌ์ฉํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค!
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
๊ฐํ ์ฐธ์กฐ์ ๋์ผํ์ง๋ง, ํ๊ฐ์ง ๋ฌ๋ผ์ง ์ ์ tanant๊ฐ weak์ผ๋ก ์ ์ธ๋์๋ค๋ ์ ์ด์์.
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
john!.apartment = number73
number73!.tenant = john
์์ ๊ฐ์ ์ํฉ์ ๋์ผํ๊ฒ ์๊ฐํด๋ณด๋ฉด, john๊ณผ number73์ ์๋ก์ Object๊ฐ ์ฐธ์กฐ๋ฅผ ํ๊ฒ ๋์ฃ ?
ํ์ง๋ง ์ด๋ฒ์๋ weak๋ก ์ ์ธํ๊ธฐ ๋๋ฌธ์ Object๊ฐ ์ฝํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ๋๋๋ฐ,
john = nil
john์ nil๋ก ํ ๋นํด john์ด ๊ฐ์ง๋ ๊ฐํ ์ฐธ์กฐ๋ฅผ ๊นจ๋ฉด, Person Object์ ๋ํ ๊ฐํ ์ฐธ์กฐ๊ฐ ์๋์ ๊ฐ์ด ์ฌ๋ผ์ง๋๋ค!
์ด์ Apartment์ ๋ํ ๊ฐํ ์ฐธ์กฐ๋ number73์ ๋ํ ๊ฒ๋ง ๋จ์์๊ณ , ์ด๋ง์ ๋ ๊นจ๋ฒ๋ฆฌ๋ฉด ๋ ์ด์ ๊ฐ๋ ฅ ์ฐธ์กฐ๋ ๋จ์์์ง ์๊ฒ ๋๋๊ฑฐ์์.
number73 = nil
์์์ ๊ฐํ์ฐธ์กฐ ์ผ๋๋ Object ์๋ก๊ฐ ์ฐธ์กฐ๋ฅผ ํ๊ณ ์์ด์ Garbage Collector๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ด Object๋ค์ ์ง์๋ฒ๋ฆฌ์ง ์์๋๋ฐ, ์ฝํ ์ฐธ์กฐ๋ก ์ฐ๊ฒฐ๋์ด ์๊ธฐ ๋๋ฌธ์, ์์์ ์ค๋ช ํ๋ฏ์ด ์๋ฏธ์๋ Object๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ์ ๊นจ๋ฒ๋ฆฌ๊ณ Reference Count๊ฐ 0์ด ๋์ด ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ๋ผ์ง๊ฒ ๋๊ณ , ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ ์ ์๊ฒ ๋ฉ๋๋ค!
๋ง์ง๋ง์ผ๋ก unowned Reference Cycle(๋ฏธ์์ ์ฐธ์กฐ ์ํ)์ ์ฝํ ์ฐธ์กฐ์ ๋น์ทํ๊ฒ Obejct์ ๋ํด ์ฝํ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์. ๋ค๋ง Concept์ด ๋ค๋ฅธ๊ฒ ์๋ค๋ฉด weak์ nil์ ๊ฐ์ง ์ ์๋๋ก ํญ์ Optional๋ก ์ ์ํ๋๋ฐ, unowned๋ ๋ฐ๋์ ์ด๋ค ๊ฐ์ ๊ฐ์ ธ์ผํ๋ค๋ ๊ฑฐ์์! ์ฆ Optional๋ก ์ ์ํ ์ ์์ด์. unowned์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ ์ธ์ ์์ unowned ํค์๋๋ฅผ ๋ถ์ด๋ฉด ๋ฉ๋๋ค.
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit { println("\(name) is being deinitialized") }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit { println("Card #\(number) is being deinitialized") }
}
์ด๋ ๊ฒ Customer, CreditCard ํด๋์ค๊ฐ ์์๋, CreditCard๊ฐ ๋ฏธ์์ ์ฐธ์กฐ ํ๋๋ก ์ ์ธํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฐธ์กฐ ๊ตฌ์ฑ์ ๊ฐ์ง๊ฒ ๋๊ฒ ์ฃ ?
var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
์ฌ๊ธฐ์ john์ ๊ฐ๋ ฅ ์ฐธ์กฐ๋ฅผ ๊นจ๋ฉด
john = nil
์ด๋ ๊ฒ ์ฝํ ์ฐธ์กฐ๋ง ๋จ์์, Object ๋ผ๋ฆฌ์ ์ฐธ์กฐ๋ ์์ฐ์ค๋ฝ๊ฒ ๊นจ์ง๊ณ Garbage Collector์ ์ํด ๋ฉ๋ชจ๋ฆฌ์์์ ์ง์์ง๊ฒ ๋ฉ๋๋ค!
์ฌ์ค unowned๋.. ์ ๋ nil์ด ์๋ Object..!? ๋ผ๋ ์ํฉ์ ์ค์ ๋ก ์ฌ์ฉํ๊ธฐ์๋ ๋ง์ ์ํ์ด ๋ฐ๋ฅด๋ ๋ฐฉ๋ฒ์ด์์.
๊ทธ๋ฆฌ๊ณ ์๋ง ๋ณดํต ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ํด์ weak์ ์ฌ์ฉํ๋๊ฒ ๋ณดํธ์ ์ผ ๊ฑฐ์์!
์ด๋ ๊ฒ Swift์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๊ณผ, ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์๋ ํฌ์ธํธ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์๋ณด์๋๋ฐ์!!
์ค๋์ ์ข ๋ณต์กํ์ง๋ง ๋งค์ฐ ์ค์ํ ๊ฐ๋ ์ ์ ๋ฆฌํด๋ดค๋๋ฐ, ํํํ ๋ค์ ๋ณด๋ฉด์ ์์ง ๋ง์์ผ๊ฒ ์ด์. ๐๐
์ค๋๋ ๋๊ตฐ๊ฐ์๊ฒ ๋์์ด ๋์๊ธธ ๐
'iOS [Swift] > ๊ธฐ์ด๋ฅผ ํํํ!' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] CGRect, CGSize, CGPoint (0) | 2021.02.05 |
---|---|
[Swift] Storyboard vs Programmatic UI (0) | 2021.02.05 |
[Swift] ARC (Automatic Reference Counting) (0) | 2021.01.29 |
[Swift] ์๊ณ ๋ฆฌ์ฆ ์ฝ๋ฉ์ ์ ์ฉํ Tip๋ค! (0) | 2021.01.05 |
[Swift] Core Data(2) ์ค์ตํด๋ณด๊ธฐ (0) | 2020.12.21 |