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와 메모리 관리

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

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
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
FIDO Alliance
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
FIDO Alliance
 
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
FIDO Alliance
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream Processing
 
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
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
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
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 

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 의 차이