Skip to content

Commit 500c7de

Browse files
authored
Create ARC.swift
1 parent f152879 commit 500c7de

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

Additional/ARC.swift

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
2+
import Foundation
3+
4+
/* ARC: 힙 영역과 관련 */
5+
// 스택: 구조체, 열거형 등 (값타입), 힙: 클래스, 클로저 등(참조 타입)
6+
// delegate, closure 등에서 순환참조가 발생할 수 있고, 이를 방지하기 위해 ARC를 사용
7+
// ARC(컴파일시점에 확정) <-> MRC(ex: GC(java) 런타임 시점에 확정)
8+
9+
class Owner {
10+
let name: String
11+
12+
init(name: String) {
13+
print("Owner Init")
14+
self.name = name
15+
}
16+
17+
deinit {
18+
print("Owner Deinit")
19+
}
20+
}
21+
22+
class CreditCard {
23+
let name: String
24+
25+
init(name: String) {
26+
print("CreditCard Init")
27+
self.name = name
28+
}
29+
30+
deinit {
31+
print("CreditCard Deinit")
32+
}
33+
}
34+
35+
// 옵셔널 ?
36+
//annot assign to value: 'ruppy' is a 'let' constant
37+
//let -> 변할 수 없음 -> var로 바꾸면 될까
38+
//error: 'nil' cannot be assigned to type 'Owner'
39+
//nil이 들어올수있다는 것을 명시하면 오류가 나지 않음
40+
41+
let a: Int? = nil
42+
//a = nil //불가능, let은 불변값임
43+
44+
var b: Int? = 2
45+
//b = nil //불가능, 타입 명시 필요
46+
47+
// 정상적인 deinit
48+
//왜? 인스턴스 생성으로 Onwer(instance) RC 1, CreditCard(instance) RC 1
49+
var ruppy: Owner? = Owner(name: "ruppy")
50+
var ruppyCard: CreditCard? = CreditCard(name: "ruppyCard")
51+
ruppy = nil
52+
ruppyCard = nil
53+
54+
55+
class DogOwner {
56+
let name: String
57+
var dog: Dog?
58+
59+
init(name: String) {
60+
print("DogOwner Init")
61+
self.name = name
62+
}
63+
64+
deinit {
65+
print("DogOwner Deinit")
66+
}
67+
}
68+
69+
class Dog {
70+
let name: String
71+
weak var owner: DogOwner?
72+
73+
init(name: String) {
74+
print("Dog Init")
75+
self.name = name
76+
}
77+
78+
deinit {
79+
print("Dog Deinit")
80+
}
81+
}
82+
83+
var dogOwner: DogOwner? = DogOwner(name: "ruppy") //DogOwner RC 1
84+
var dog: Dog? = Dog(name: "rupDog") //Dog RC 1
85+
86+
dog?.owner = dogOwner //DogOwner RC 1
87+
dogOwner?.dog = dog //Dog RC 2
88+
89+
dog = nil //RC 2 > RC 1 > owner가 해제되면서 RC 0
90+
dogOwner = nil //RC1 > RC 0 으로 해제
91+
92+
dog?.owner
93+
dogOwner?.dog
94+
95+
//weak: 수명이 더 짧은. 더 빨리 해제되는 인스턴스를 가리키는 프로퍼티한테 weak를 선언을 함 > 하지만 다 붙이는게 통상적으로 편함
96+
//unowned: 수명이 다른 인스턴스와 동일하거나 더 긴 경우에 unonwed를 붙임 > 메모리가 해제되어도 주소값 남아있어서 접근하면 문제
97+
//weak와 unonwned: 둘 다 RC를 올리지 않음
98+
99+
func test1(){
100+
var number = 10
101+
102+
//캡처리스트: 복사 형태로 값을 가져옴. 외부와 독립적 값 사용
103+
let closure = { [number] in
104+
print("\(number * 2)")
105+
}
106+
107+
closure() //20
108+
number = 100
109+
closure() //20
110+
}
111+
112+
test1()
113+
114+
115+
func test2(){
116+
var number = 10
117+
118+
let closure = {
119+
print("\(number * 2)")
120+
}
121+
122+
closure() //20
123+
number = 100
124+
closure() //200
125+
}
126+
127+
test2()
128+
129+
// cannot use instance member 'name' within property initializer
130+
// property initializers run before 'self' is available => lazy로 시점을 늦춰야 name을 쓸수있음
131+
// 클로저 안에서 사용할때는 self를 붙이라고 함
132+
// capture 'self' explicitly to enable implicit 'self' in this closure
133+
//deinit안됨 > 왜?? self를 클로저가 잡고 있어서 RC+1
134+
//[weak self]를 통해 deinit 시켜줄 수 있음
135+
class BBORORO {
136+
let name: String
137+
138+
lazy var introduce = { [weak self] in
139+
print("안녕 난 \(self?.name ?? "루피")")
140+
}
141+
142+
init(name: String) {
143+
print("BBORORO init")
144+
self.name = name
145+
}
146+
147+
deinit {
148+
print("BBORORO Deinit")
149+
}
150+
}
151+
152+
var bbororo: BBORORO? = BBORORO(name: "뽀로로")
153+
bbororo?.introduce //함수 그자체
154+
bbororo?.introduce() //함수의 실행
155+
bbororo = nil
156+
157+
158+
//'weak' must not be applied to non-class-bound 'any RuppyProtocol'; consider adding a protocol conformance that has a class bound
159+
//protocol에 클래스 제약 걸라는 말
160+
protocol RuppyProtocol: AnyObject {
161+
func sendData()
162+
}
163+
164+
class Main: RuppyProtocol {
165+
166+
lazy var detail = {
167+
let detail = Detail()
168+
detail.delegate = self
169+
return detail
170+
}()
171+
172+
init() {
173+
print("Main Init")
174+
}
175+
176+
func sendData(){
177+
print("나 데이터야 돌아왔어")
178+
}
179+
180+
deinit {
181+
print("Main Deinit")
182+
}
183+
}
184+
185+
class Detail {
186+
weak var delegate: RuppyProtocol?
187+
188+
func dismiss(){
189+
delegate?.sendData()
190+
}
191+
192+
init(){
193+
print("Detail Init")
194+
}
195+
196+
197+
deinit {
198+
print("Detail Deinit")
199+
}
200+
}
201+
202+
var main: Main? = Main()
203+
main?.detail.dismiss()
204+
main = nil

0 commit comments

Comments
 (0)