SlideShare a Scribd company logo
1 of 56
Download to read offline
ARC and
Memory Management
in Swift
Swift 에서의 Automatic Reference Counting 과 메모리 관리
@daheenallwhite!1
메모리 관리 Reference
Counting
in Swift
- Strong
- Weak
- Unowned
- Closure
Contents
2
!3
메모리 관리의 필요성
😫😫
😫
😫
😫
😫
😫😫
😫
😫
😫 😫
😫
😫
한정된 자원
😫
🖥
Process
Program
Thread
😫😫
😫
😫
😫
😫😫
😫 😫
😫
😫
😫😫
😫
😫
😫😫
😫 😫
😫
😫😫
😫
😫
😫
😫
😫
😫 😫
😫
!4
Swift 에서 메모리 사용
Code
Static
Heap
Stack Value Type
Reference Type
!5
Reference Counting
필요한 동안만 메모리에 있도록 하자!
💡
해당 instance를 참조하면 count +1
해당 instance를 필요로 하는 애들의 숫자를 세자!
6
메모리에서 class instance 생명 주기
1. Allocation : 인스턴스를 위한 메모리 공간 찾기 🔍
2. Initialization : init()
3. 인스턴스 사용
4. Deinitialization : deinit() (메모리 회수 직전)
5. Deallocation
!7
Reference Counting 적용한 코드
class Point {
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
// use point1
// use point2
작성한 코드
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
Swift 컴파일러가 ARC 적용하여 생성한 코드
!8
Reference Counting - Runtime
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2
!9
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 1
x: 0
y: 0
Reference Counting - Runtime
!10
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 1
x: 0
y: 0
Reference Counting - Runtime
!11
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 2
x: 0
y: 0
Reference Counting - Runtime
!12
Reference Counting - Runtime
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 1
x: 0
y: 0
!13
Reference Counting - Runtime
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 1
x: 0
y: 0
!14
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 0
x: 0
y: 0
Reference Counting - Runtime
!15
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
point1
point2 refCount: 0
x: 0
y: 0
Reference Counting - Runtime
!16
class Point {
var refCount: Int
var x, y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
retain(point2)
// use point1
release(point1)
// use point2
release(point2)
HeapStack
Reference Counting - Runtime
!17
MRC / ARC
Manual Automatic
Apple release note - Transitioning to ARC
Strong Reference
Class TabletClass User
class User {
let name: String
var tablet: Tablet?
init(name: String) {
self.name = name
print("생성: User (self.name)")
}
deinit {
print("소멸: User (self.name)")
}
}
class Tablet {
let model: String
var owner: User?
init(model: String) {
self.model = model
print("생성: Phone (self.model)")
}
deinit {
print("소멸: Phone (self.model)")
}
}
!18
🧒
!19
Strong Reference
var iPadProvar dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
!20
Strong Reference
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
!21
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!21
strong strong
strong
strong
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
!22
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!22
strong strong
strong
strong
// 박살남.. 😇 😭
iPadPro = nil
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
!23
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!23
strong
strong
strong
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
// 박살남.. 😇 😭
iPadPro = nil
!24
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!24
strong
strong
strong
// 박살남.. 😇 😭
iPadPro = nil
// 집 나감 🤬
dana = nil
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
!25
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!25
strong
strong
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
// 박살남.. 😇 😭
iPadPro = nil
// 집 나감 🤬
dana = nil
!26
Strong Reference Cycle
var iPadProvar 흰
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
!26
strong
strong
// 박살남.. 😇 😭
iPadPro = nil
// 집 나감 🤬
흰 = nil
var dana
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
// 박살남.. 😇 😭
iPadPro = nil
// 집 나감 🤬
dana = nil
!27
Strong Reference Cycle 해결
원인
Reference count 를 0으로 만들지 못하게 함
두 인스턴스의 상대적인 수명을 알 수 없음
해결
Strong Reference 일 때만 reference count를 세자!
상대적인 수명에 대한 정보를 미리 알려주자!
해결 방법 - weak & unowned references
weak unowned
수명>
weak
<=
unowned
해당 instance에서 참조하는 instance가
더 적은 시간동안 메모리에 있는 경우
해당 instance에서 참조하는 instance가
더 오래 혹은 같은 시간동안
메모리에 있어야 하는 경우
참조하는 속성 값 == nil
인스턴스가 있을수도/없을수도
Optional
상대 인스턴스에 의존관계인 경우
항상 있어야 할 때
Non-optional
해결 - Weak Reference
Class TabletClass User
class User {
let name: String
weak var tablet: Tablet?
init(name: String) {
self.name = name
print("생성: User (self.name)")
}
deinit {
print("소멸: User (self.name)")
}
}
class Tablet {
let model: String
var owner: User?
init(model: String) {
self.model = model
print("생성: Tablet (self.model)")
}
deinit {
print("소멸: Tablet (self.model)")
}
}
!29
🧒
해결 - Weak Reference
!30!30!30
strong strong
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
weak
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
strong
var iPadProvar dana
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!31!31!31
strong
weak
<Tablet Instance>
model: “iPad Pro”
owner: <User Instance>
strong
var iPadProvar 흰
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
var dana
해결 - Weak Reference
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!32!32!32
strong
weak
var iPadPro
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
var dana
해결 - Weak Reference
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!33!33!33
strong
var iPadPro
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
var dana
nil
// 집 나감 🤬
dana = nil
해결 - Weak Reference
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!34!34!34
strong
var iPadPro
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
var dana
nil
해결 - Weak Reference
// 집 나감 🤬
dana = nil
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!35!35!35
var iPadPro
<User Instance>
name: “Dana”
tablet: <Tablet Instance>
var dana
nil
해결 - Weak Reference
// 집 나감 🤬
dana = nil
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!36!36!36
var iPadProvar dana
해결 - Weak Reference
// 집 나감 🤬
dana = nil
var dana: User? = User(name: "Dana")
var iPadPro: Tablet? = Tablet(model: "iPad Pro")
// 새로 샀다!!
dana!.tablet = iPadPro
iPadPro!.owner = dana
// 박살남
iPadPro = nil
!37!37!37
Unowned Reference
Class NetflixMembershipClass User
class NetflixMembership {
let plan: String
let owner: User
init(plan: String, owner: User) {
self.plan = plan
self.owner = owner
print("생성: (self.plan) 구독")
}
deinit {
print("소멸: (self.plan) 구독")
}
}
class User {
let name: String
var netflixMembership:
NetflixMembership?
init(name: String) {
self.name = name
print("생성: User (self.name)")
}
deinit {
print("소멸: User (self.name)")
}
}
unowned let owner: User
🧒
!38!38!38
해결 - Unowned Reference
var dana
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
!39!39!39
var 흰
strong
<User Instance>
name: “Dana”
streamingMembership: 

<StreamingMembership Instance>
var dana
해결 - Unowned Reference
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
!40!40!40
strong
<NetflixMembership Instance>
Plan : “Premium”
owner: <User Instance>
strong
<User Instance>
name: “Dana”
streamingMembership: 

<StreamingMembership Instance>
var dana
해결 - Unowned Reference
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
!41!41!41
strong
<NetflixMembership Instance>
Plan : “Premium”
owner: <User Instance>
strong
unowned
<User Instance>
name: “Dana”
streamingMembership: 

<StreamingMembership Instance>
var dana
해결 - Unowned Reference
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
!42!42!42
strong
<NetflixMembership Instance>
Plan : “Premium”
owner: <User Instance>
strong
unowned
// 탈퇴..
Dana = nil
<User Instance>
name: “Dana”
streamingMembership: 

<StreamingMembership Instance>
var dana
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
해결 - Unowned Reference
!43!43!43
<NetflixMembership Instance>
Plan : “Premium”
owner: <User Instance>
strong
unowned
// 탈퇴..
Dana = nil
<User Instance>
name: “Dana”
streamingMembership: 

<StreamingMembership Instance>
var dana
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
해결 - Unowned Reference
!44!44!44
<NetflixMembership Instance>
Plan : “Premium”
owner: <User Instance>
unowned
// 탈퇴..
Dana = nil
var dana
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
해결 - Unowned Reference
!45!45!45
// 탈퇴..
Dana = nil
var dana
var dana: User? = User(name: “Dana")
dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
해결 - Unowned Reference
!46
Strong Reference Cycle for Closure
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
!47
Strong Reference Cycle for Closure
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
var dana
<User Instance>
name: “Dana”
nickName: “white”
completeUserName: 

( ) -> String
( ) -> String
self.name self.nickName
strong
strong
strong
!48
Strong Reference Cycle for Closure
var 흰
( ) -> String
self.name self.nickName
strong
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
strong
var dana
<User Instance>
name: “Dana”
nickName: “white”
completeUserName: 

( ) -> String
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
[unowned self] in
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
!49
var 흰
( ) -> String
self.name self.nickName
unowned
strong
strong
해결 - Capture List
var dana
<User Instance>
name: “Dana”
nickName: “white”
completeUserName: 

( ) -> String
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
[unowned self] in
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
!50
var 흰
( ) -> String
self.name self.nickName
unowned
strong
var dana
<User Instance>
name: “Dana”
nickName: “white”
completeUserName: 

( ) -> String
해결 - Capture List
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
[unowned self] in
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
!51
( ) -> String
self.name self.nickName
unowned
var dana
해결 - Capture List
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
class User {
let name: String
var nickName: String?
init(name: String, nickName: String? = nil) {
self.name = name
self.nickName = nickName
}
lazy var completeUserName: () -> String = {
[unowned self] in
if let nickName = self.nickName {
return "(self.name) ((nickName))"
} else {
return "(self.name)"
}
}
deinit {
print("탈퇴: User (self.name)")
}
}
!52
var dana
해결 - Capture List
var dana: User? =
User(name: "Dana", nickName: "white")
print(dana!.completeUserName())
dana = nil
!53
Summary 📌
메모리 관리 필요성
Reference Counting : 필요로 하는 애들의 수를 세자
Swift Compiler, ARC / MRC
Strong Reference Cycle : 메모리 공간 낭비의 원인
Weak / Unowned : 상대적 수명에 대한 정보를 제공해주자
Closure : of Reference Type. Capture List
!54
Strong / Weak / Unowned
raywenderlich - ARC and Memory Management in Swift
!55
Reference 📗
✦ Swift Language Guide - Automatic Reference Counting
✦ raywenderlich - ARC and Memory Management in Swift
✦ WWDC 2015 - Optimizing Swift Performance
✦ WWDC 2016 - Understanding Swift Performance
✦ ARC Release Note
✦ Soulpark blog - Automatic Reference Counting (ARC)
!56
더 알아보기 🔍
✦ Value type이 메모리에서 관리되는 방식
✦ Understanding Swift Performance - WWDC 2016
✦ 메모리 관리 방식을 고려한 Swift 성능 올리기
✦ Optimizing Swift Performance - WWDC 2015
✦ Understanding Swift Performance - WWDC 2016
✦ Object-C 에서 MRC/ARC
✦ ARC obj-c
✦ Transition to ARC (no longer supported?)
✦ 고급언어의 컴파일러와 프로그램의 로딩
✦ Garbage Collector 와 ARC 의 차이

More Related Content

Similar to Swift - ARC와 메모리 관리

Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanJimin Hsieh
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987乐群 陈
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesNaresha K
 
Writing a REST Interconnection Library in Swift
Writing a REST Interconnection Library in SwiftWriting a REST Interconnection Library in Swift
Writing a REST Interconnection Library in SwiftPablo Villar
 
Running Word2Vec with Chinese Wikipedia dump
Running Word2Vec with Chinese Wikipedia dumpRunning Word2Vec with Chinese Wikipedia dump
Running Word2Vec with Chinese Wikipedia dumpBilly Yang
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探台灣資料科學年會
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys AdminsPuppet
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Programming Android Application in Scala.
Programming Android Application in Scala.Programming Android Application in Scala.
Programming Android Application in Scala.Brian Hsu
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05cKaz Yoshikawa
 
Endless fun with Arduino and Eventmachine
Endless fun with Arduino and EventmachineEndless fun with Arduino and Eventmachine
Endless fun with Arduino and EventmachineBodo Tasche
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design PatternsTrevorBurnham
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
 

Similar to Swift - ARC와 메모리 관리 (20)

Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good Practices
 
Writing a REST Interconnection Library in Swift
Writing a REST Interconnection Library in SwiftWriting a REST Interconnection Library in Swift
Writing a REST Interconnection Library in Swift
 
Running Word2Vec with Chinese Wikipedia dump
Running Word2Vec with Chinese Wikipedia dumpRunning Word2Vec with Chinese Wikipedia dump
Running Word2Vec with Chinese Wikipedia dump
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys Admins
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Programming Android Application in Scala.
Programming Android Application in Scala.Programming Android Application in Scala.
Programming Android Application in Scala.
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Endless fun with Arduino and Eventmachine
Endless fun with Arduino and EventmachineEndless fun with Arduino and Eventmachine
Endless fun with Arduino and Eventmachine
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design Patterns
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
JavaScript Abstraction
JavaScript AbstractionJavaScript Abstraction
JavaScript Abstraction
 
Concurrency
ConcurrencyConcurrency
Concurrency
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
 

Recently uploaded

Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctBrainSell Technologies
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform EngineeringMarcus Vechiato
 
How to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in PakistanHow to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in Pakistandanishmna97
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxFIDO Alliance
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!Memoori
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxMasterG
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimaginedpanagenda
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentationyogeshlabana357357
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxFIDO Alliance
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptxFIDO Alliance
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 

Recently uploaded (20)

Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
How to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in PakistanHow to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in Pakistan
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 

Swift - ARC와 메모리 관리

  • 1. ARC and Memory Management in Swift Swift 에서의 Automatic Reference Counting 과 메모리 관리 @daheenallwhite!1
  • 2. 메모리 관리 Reference Counting in Swift - Strong - Weak - Unowned - Closure Contents 2
  • 3. !3 메모리 관리의 필요성 😫😫 😫 😫 😫 😫 😫😫 😫 😫 😫 😫 😫 😫 한정된 자원 😫 🖥 Process Program Thread 😫😫 😫 😫 😫 😫😫 😫 😫 😫 😫 😫😫 😫 😫 😫😫 😫 😫 😫 😫😫 😫 😫 😫 😫 😫 😫 😫 😫
  • 4. !4 Swift 에서 메모리 사용 Code Static Heap Stack Value Type Reference Type
  • 5. !5 Reference Counting 필요한 동안만 메모리에 있도록 하자! 💡 해당 instance를 참조하면 count +1 해당 instance를 필요로 하는 애들의 숫자를 세자!
  • 6. 6 메모리에서 class instance 생명 주기 1. Allocation : 인스턴스를 위한 메모리 공간 찾기 🔍 2. Initialization : init() 3. 인스턴스 사용 4. Deinitialization : deinit() (메모리 회수 직전) 5. Deallocation
  • 7. !7 Reference Counting 적용한 코드 class Point { var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 // use point1 // use point2 작성한 코드 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) Swift 컴파일러가 ARC 적용하여 생성한 코드
  • 8. !8 Reference Counting - Runtime class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2
  • 9. !9 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 1 x: 0 y: 0 Reference Counting - Runtime
  • 10. !10 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 1 x: 0 y: 0 Reference Counting - Runtime
  • 11. !11 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 2 x: 0 y: 0 Reference Counting - Runtime
  • 12. !12 Reference Counting - Runtime class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 1 x: 0 y: 0
  • 13. !13 Reference Counting - Runtime class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 1 x: 0 y: 0
  • 14. !14 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 0 x: 0 y: 0 Reference Counting - Runtime
  • 15. !15 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack point1 point2 refCount: 0 x: 0 y: 0 Reference Counting - Runtime
  • 16. !16 class Point { var refCount: Int var x, y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point1 = Point(x: 0, y: 0) let point2 = point1 retain(point2) // use point1 release(point1) // use point2 release(point2) HeapStack Reference Counting - Runtime
  • 17. !17 MRC / ARC Manual Automatic Apple release note - Transitioning to ARC
  • 18. Strong Reference Class TabletClass User class User { let name: String var tablet: Tablet? init(name: String) { self.name = name print("생성: User (self.name)") } deinit { print("소멸: User (self.name)") } } class Tablet { let model: String var owner: User? init(model: String) { self.model = model print("생성: Phone (self.model)") } deinit { print("소멸: Phone (self.model)") } } !18 🧒
  • 19. !19 Strong Reference var iPadProvar dana <User Instance> name: “Dana” tablet: <Tablet Instance> <Tablet Instance> model: “iPad Pro” owner: <User Instance> var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro")
  • 20. !20 Strong Reference var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana var dana <User Instance> name: “Dana” tablet: <Tablet Instance>
  • 21. !21 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !21 strong strong strong strong var dana <User Instance> name: “Dana” tablet: <Tablet Instance>
  • 22. !22 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !22 strong strong strong strong // 박살남.. 😇 😭 iPadPro = nil var dana <User Instance> name: “Dana” tablet: <Tablet Instance>
  • 23. !23 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !23 strong strong strong var dana <User Instance> name: “Dana” tablet: <Tablet Instance> // 박살남.. 😇 😭 iPadPro = nil
  • 24. !24 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !24 strong strong strong // 박살남.. 😇 😭 iPadPro = nil // 집 나감 🤬 dana = nil var dana <User Instance> name: “Dana” tablet: <Tablet Instance>
  • 25. !25 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !25 strong strong var dana <User Instance> name: “Dana” tablet: <Tablet Instance> // 박살남.. 😇 😭 iPadPro = nil // 집 나감 🤬 dana = nil
  • 26. !26 Strong Reference Cycle var iPadProvar 흰 <Tablet Instance> model: “iPad Pro” owner: <User Instance> !26 strong strong // 박살남.. 😇 😭 iPadPro = nil // 집 나감 🤬 흰 = nil var dana <User Instance> name: “Dana” tablet: <Tablet Instance> // 박살남.. 😇 😭 iPadPro = nil // 집 나감 🤬 dana = nil
  • 27. !27 Strong Reference Cycle 해결 원인 Reference count 를 0으로 만들지 못하게 함 두 인스턴스의 상대적인 수명을 알 수 없음 해결 Strong Reference 일 때만 reference count를 세자! 상대적인 수명에 대한 정보를 미리 알려주자!
  • 28. 해결 방법 - weak & unowned references weak unowned 수명> weak <= unowned 해당 instance에서 참조하는 instance가 더 적은 시간동안 메모리에 있는 경우 해당 instance에서 참조하는 instance가 더 오래 혹은 같은 시간동안 메모리에 있어야 하는 경우 참조하는 속성 값 == nil 인스턴스가 있을수도/없을수도 Optional 상대 인스턴스에 의존관계인 경우 항상 있어야 할 때 Non-optional
  • 29. 해결 - Weak Reference Class TabletClass User class User { let name: String weak var tablet: Tablet? init(name: String) { self.name = name print("생성: User (self.name)") } deinit { print("소멸: User (self.name)") } } class Tablet { let model: String var owner: User? init(model: String) { self.model = model print("생성: Tablet (self.model)") } deinit { print("소멸: Tablet (self.model)") } } !29 🧒
  • 30. 해결 - Weak Reference !30!30!30 strong strong <User Instance> name: “Dana” tablet: <Tablet Instance> weak <Tablet Instance> model: “iPad Pro” owner: <User Instance> strong var iPadProvar dana var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 31. !31!31!31 strong weak <Tablet Instance> model: “iPad Pro” owner: <User Instance> strong var iPadProvar 흰 <User Instance> name: “Dana” tablet: <Tablet Instance> var dana 해결 - Weak Reference var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 32. !32!32!32 strong weak var iPadPro <User Instance> name: “Dana” tablet: <Tablet Instance> var dana 해결 - Weak Reference var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 33. !33!33!33 strong var iPadPro <User Instance> name: “Dana” tablet: <Tablet Instance> var dana nil // 집 나감 🤬 dana = nil 해결 - Weak Reference var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 34. !34!34!34 strong var iPadPro <User Instance> name: “Dana” tablet: <Tablet Instance> var dana nil 해결 - Weak Reference // 집 나감 🤬 dana = nil var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 35. !35!35!35 var iPadPro <User Instance> name: “Dana” tablet: <Tablet Instance> var dana nil 해결 - Weak Reference // 집 나감 🤬 dana = nil var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 36. !36!36!36 var iPadProvar dana 해결 - Weak Reference // 집 나감 🤬 dana = nil var dana: User? = User(name: "Dana") var iPadPro: Tablet? = Tablet(model: "iPad Pro") // 새로 샀다!! dana!.tablet = iPadPro iPadPro!.owner = dana // 박살남 iPadPro = nil
  • 37. !37!37!37 Unowned Reference Class NetflixMembershipClass User class NetflixMembership { let plan: String let owner: User init(plan: String, owner: User) { self.plan = plan self.owner = owner print("생성: (self.plan) 구독") } deinit { print("소멸: (self.plan) 구독") } } class User { let name: String var netflixMembership: NetflixMembership? init(name: String) { self.name = name print("생성: User (self.name)") } deinit { print("소멸: User (self.name)") } } unowned let owner: User 🧒
  • 38. !38!38!38 해결 - Unowned Reference var dana var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
  • 39. !39!39!39 var 흰 strong <User Instance> name: “Dana” streamingMembership: <StreamingMembership Instance> var dana 해결 - Unowned Reference var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
  • 40. !40!40!40 strong <NetflixMembership Instance> Plan : “Premium” owner: <User Instance> strong <User Instance> name: “Dana” streamingMembership: <StreamingMembership Instance> var dana 해결 - Unowned Reference var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
  • 41. !41!41!41 strong <NetflixMembership Instance> Plan : “Premium” owner: <User Instance> strong unowned <User Instance> name: “Dana” streamingMembership: <StreamingMembership Instance> var dana 해결 - Unowned Reference var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!)
  • 42. !42!42!42 strong <NetflixMembership Instance> Plan : “Premium” owner: <User Instance> strong unowned // 탈퇴.. Dana = nil <User Instance> name: “Dana” streamingMembership: <StreamingMembership Instance> var dana var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!) 해결 - Unowned Reference
  • 43. !43!43!43 <NetflixMembership Instance> Plan : “Premium” owner: <User Instance> strong unowned // 탈퇴.. Dana = nil <User Instance> name: “Dana” streamingMembership: <StreamingMembership Instance> var dana var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!) 해결 - Unowned Reference
  • 44. !44!44!44 <NetflixMembership Instance> Plan : “Premium” owner: <User Instance> unowned // 탈퇴.. Dana = nil var dana var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!) 해결 - Unowned Reference
  • 45. !45!45!45 // 탈퇴.. Dana = nil var dana var dana: User? = User(name: “Dana") dana!.netflixMembership = NetflixMembership(plan: "Premium", owner: dana!) 해결 - Unowned Reference
  • 46. !46 Strong Reference Cycle for Closure class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } }
  • 47. class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } !47 Strong Reference Cycle for Closure var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil var dana <User Instance> name: “Dana” nickName: “white” completeUserName: ( ) -> String ( ) -> String self.name self.nickName strong strong strong
  • 48. !48 Strong Reference Cycle for Closure var 흰 ( ) -> String self.name self.nickName strong class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } strong var dana <User Instance> name: “Dana” nickName: “white” completeUserName: ( ) -> String var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil
  • 49. class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { [unowned self] in if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } !49 var 흰 ( ) -> String self.name self.nickName unowned strong strong 해결 - Capture List var dana <User Instance> name: “Dana” nickName: “white” completeUserName: ( ) -> String var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil
  • 50. class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { [unowned self] in if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } !50 var 흰 ( ) -> String self.name self.nickName unowned strong var dana <User Instance> name: “Dana” nickName: “white” completeUserName: ( ) -> String 해결 - Capture List var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil
  • 51. class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { [unowned self] in if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } !51 ( ) -> String self.name self.nickName unowned var dana 해결 - Capture List var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil
  • 52. class User { let name: String var nickName: String? init(name: String, nickName: String? = nil) { self.name = name self.nickName = nickName } lazy var completeUserName: () -> String = { [unowned self] in if let nickName = self.nickName { return "(self.name) ((nickName))" } else { return "(self.name)" } } deinit { print("탈퇴: User (self.name)") } } !52 var dana 해결 - Capture List var dana: User? = User(name: "Dana", nickName: "white") print(dana!.completeUserName()) dana = nil
  • 53. !53 Summary 📌 메모리 관리 필요성 Reference Counting : 필요로 하는 애들의 수를 세자 Swift Compiler, ARC / MRC Strong Reference Cycle : 메모리 공간 낭비의 원인 Weak / Unowned : 상대적 수명에 대한 정보를 제공해주자 Closure : of Reference Type. Capture List
  • 54. !54 Strong / Weak / Unowned raywenderlich - ARC and Memory Management in Swift
  • 55. !55 Reference 📗 ✦ Swift Language Guide - Automatic Reference Counting ✦ raywenderlich - ARC and Memory Management in Swift ✦ WWDC 2015 - Optimizing Swift Performance ✦ WWDC 2016 - Understanding Swift Performance ✦ ARC Release Note ✦ Soulpark blog - Automatic Reference Counting (ARC)
  • 56. !56 더 알아보기 🔍 ✦ Value type이 메모리에서 관리되는 방식 ✦ Understanding Swift Performance - WWDC 2016 ✦ 메모리 관리 방식을 고려한 Swift 성능 올리기 ✦ Optimizing Swift Performance - WWDC 2015 ✦ Understanding Swift Performance - WWDC 2016 ✦ Object-C 에서 MRC/ARC ✦ ARC obj-c ✦ Transition to ARC (no longer supported?) ✦ 고급언어의 컴파일러와 프로그램의 로딩 ✦ Garbage Collector 와 ARC 의 차이