SlideShare une entreprise Scribd logo
1  sur  35
Télécharger pour lire hors ligne
Naruki Chigira - Timers inc.
GitHub: naru-jpn, Twitter: @naruchigi
Unowned / Weak References with Closure
変数の生存期間、気にしてますか?
クロージャ内で保持される変数、追えますか?
DispatchQueue.main.async { [weak self] in
// ...
}
クロージャ内で『 とりあえず [weak self] 』してませんか?
Playground で挙動を細かく見てみよう
https://gist.github.com/naru-jpn/fa4c39ce2eda8a803358dad75d04058d
class Executor {
// MARK: Exeute stored procedure
let procedure: () -> ()
init(procedure: @escaping () -> ()) {
self.procedure = procedure
}
func execute() {
self.procedure()
}
// MARK: Static execution
static func execute(procedure: () -> ()) {
procedure()
}
}
クロージャを実行するクラス Executor
class Object {
var child: Object?
weak var weakChild: Object?
var closure: (() -> ())?
weak var currentExecutor: Executor?
}
観測用クラス Object
weak var weakObject: Object? = nil
// スコープ内外での挙動を見るために if 文でネストさせる
// object が解放されていれば weakObject の中身は nil になる
if true {
let object: Object = Object()
weakObject = object
print(“(weakObject)") // nil or not nil?
}
print(“(weakObject)") // nil or not nil?
変数が解放されているかどうかの確認
object object
if true {
let object: Object = Object()
weakObject = object // 1
}
// 2
1. 変数はスコープを抜けたら解放される
object
child
object
child
if true {
let object: Object = Object()
object.child = object
weakObject = object // 1
}
// 2
weakObject?.child = nil
2. 参照によるメモリリーク
object
child
object
child
if true {
let object: Object = Object()
object.weakChild = object
weakObject = object // 1
}
// 2
weakObject?.child = nil
3. weak を使ってメモリリークしないようにしたケース
循環参照は当然避けましょう
object
closure
object
closure
if true {
let object: Object = Object()
object.closure = {
print("(object)")
}
weakObject = object // 1
}
// 2
weakObject?.closure = nil
4. クロージャからの参照によるメモリリーク
object
closure
object
closure
if true {
let object: Object = Object()
object.closure = { [weak object] in
print("(object)")
}
weakObject = object // 1
}
// 2
5. [weak ---] を使ってメモリリークしないようにしたケース
クロージャの循環参照にも注意
object
closure
object object
closure
object
スコープ内 関数実行時 関数終了時 スコープ外
Executor Executor
extension Object {
func printWeakSelf() {
let executor: Executor = Executor(procedure: { [weak self] in
debugPrint("(self)")
})
executor.execute()
}
}
6. Executor のクロージャ内で [weak self] を使う場合
object
closure
object object
closure
object
スコープ内 関数実行時 関数終了時 スコープ外
Executor Executor
if true {
let object: Object = Object()
object.printWeakSelf()
weakObject = object
}
6. Executor のクロージャ内で [weak self] を使う場合
object
closure
object object
closure
object
Executor Executor
スコープ内 関数実行時 関数終了時 スコープ外
extension Object {
func printSelf() {
let executor: Executor = Executor(procedure: {
print("(self)")
})
executor.execute()
}
}
7. Executor のクロージャ内で [weak self] を使わない場合
object
closure
object object
closure
object
Executor Executor
スコープ内 関数実行時 関数終了時 スコープ外
if true {
let object: Object = Object()
object.printSelf()
weakObject = object
}
7. Executor のクロージャ内で [weak self] を使わない場合
クロージャ内で self を参照してもリークしない場合もある
非同期処理待機時 非同期処理終了時関数実行時
object
closure closure
Executor
object
closure
Executor
extension Object {
func printAsynchronousWeakSelf() {
let executor: Executor = Executor(procedure: {
let time: DispatchTime = .now() + 1.0
DispatchQueue.global().asyncAfter(deadline: time, execute: { [weak self] in
print("(self)")
})
})
executor.execute()
self.currentExecutor = executor
}
}
8. 非同期処理で [weak self] を使う場合
非同期処理待機時 非同期処理終了時関数実行時
object
closure closure
Executor
object
closure
Executor
if true {
let object: Object = Object()
object.printAsynchronousSelf()
weakObject = object
}
sleep(UInt32(3.0))
8. 非同期処理で [weak self] を使う場合
非同期処理待機時 非同期処理終了時関数実行時
object
closure
object
closure
Executor
object
closure
Executor
extension Object {
func printAsynchronousSelf() {
let executor: Executor = Executor(procedure: {
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0, execute: {
print("(self)")
})
})
executor.execute()
self.currentExecutor = executor
}
}
9. 非同期処理で [weak self] を使わない場合
非同期処理待機時 非同期処理終了時関数実行時
object
closure
object
closure
Executor
object
closure
Executor
if true {
let object: Object = Object()
object.printAsynchronousSelf()
weakObject = object
}
sleep(UInt32(3.0))
9. 非同期処理で [weak self] を使わない場合
非同期処理ではコールバック時に
object が生存しているかどうかが変わってくる
ただし、リークしないことに変わりはない
目的に応じて使い分けられるようになりたいですね🤗
いつか [weak self] を見たときに思いを馳せてみてください
Motivation / Concept
https://developers.google.com/protocol-buffers/
Template
message

Contenu connexe

Tendances

テストを書こう、Unity編
テストを書こう、Unity編テストを書こう、Unity編
テストを書こう、Unity編Hiroto Imoto
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...なおき きしだ
 
ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3Tomoyuki Sato
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しようUnity Technologies Japan K.K.
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
Apache Auroraの始めかた
Apache Auroraの始めかたApache Auroraの始めかた
Apache Auroraの始めかたMasahito Zembutsu
 
後期第三回ネットワークチーム講座資料
後期第三回ネットワークチーム講座資料後期第三回ネットワークチーム講座資料
後期第三回ネットワークチーム講座資料densan_teacher
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsYoshifumi Kawai
 
Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Norito Agetsuma
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
JVMの中身を可視化してみた
JVMの中身を可視化してみたJVMの中身を可視化してみた
JVMの中身を可視化してみたKengo Toda
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するshigeki_ohtsu
 

Tendances (20)

テストを書こう、Unity編
テストを書こう、Unity編テストを書こう、Unity編
テストを書こう、Unity編
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
 
ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3
 
About Jobs
About JobsAbout Jobs
About Jobs
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
Iocage
IocageIocage
Iocage
 
Spock's world
Spock's worldSpock's world
Spock's world
 
Apache Auroraの始めかた
Apache Auroraの始めかたApache Auroraの始めかた
Apache Auroraの始めかた
 
Unity testtool
Unity testtoolUnity testtool
Unity testtool
 
ICHIGEKI-MT 2015/03/14
ICHIGEKI-MT 2015/03/14ICHIGEKI-MT 2015/03/14
ICHIGEKI-MT 2015/03/14
 
後期第三回ネットワークチーム講座資料
後期第三回ネットワークチーム講座資料後期第三回ネットワークチーム講座資料
後期第三回ネットワークチーム講座資料
 
scala-kaigi1-sbt
scala-kaigi1-sbtscala-kaigi1-sbt
scala-kaigi1-sbt
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
Spockの基礎
Spockの基礎Spockの基礎
Spockの基礎
 
Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
JVMの中身を可視化してみた
JVMの中身を可視化してみたJVMの中身を可視化してみた
JVMの中身を可視化してみた
 
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解するそうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
 
Puppet on AWS
Puppet on AWSPuppet on AWS
Puppet on AWS
 

En vedette

Xcodeの管理を楽に - Jenkins編 -
Xcodeの管理を楽に - Jenkins編 -Xcodeの管理を楽に - Jenkins編 -
Xcodeの管理を楽に - Jenkins編 -Toshiyuki Hirata
 
Windows Azureを利用したDevOps入門
Windows Azureを利用したDevOps入門Windows Azureを利用したDevOps入門
Windows Azureを利用したDevOps入門yoichi kikuta
 
AWS Startup Tech - 宇宙と雲の間に CTO安川
AWS Startup Tech - 宇宙と雲の間に CTO安川AWS Startup Tech - 宇宙と雲の間に CTO安川
AWS Startup Tech - 宇宙と雲の間に CTO安川SORACOM,INC
 
最強のセキュリティでIoTを実装する方法
最強のセキュリティでIoTを実装する方法最強のセキュリティでIoTを実装する方法
最強のセキュリティでIoTを実装する方法Shinji Saito
 
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例SORACOM,INC
 
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川 日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川 SORACOM,INC
 
SORACOM Dev Conf #0: 新機能発表!
SORACOM Dev Conf #0: 新機能発表!SORACOM Dev Conf #0: 新機能発表!
SORACOM Dev Conf #0: 新機能発表!SORACOM,INC
 

En vedette (7)

Xcodeの管理を楽に - Jenkins編 -
Xcodeの管理を楽に - Jenkins編 -Xcodeの管理を楽に - Jenkins編 -
Xcodeの管理を楽に - Jenkins編 -
 
Windows Azureを利用したDevOps入門
Windows Azureを利用したDevOps入門Windows Azureを利用したDevOps入門
Windows Azureを利用したDevOps入門
 
AWS Startup Tech - 宇宙と雲の間に CTO安川
AWS Startup Tech - 宇宙と雲の間に CTO安川AWS Startup Tech - 宇宙と雲の間に CTO安川
AWS Startup Tech - 宇宙と雲の間に CTO安川
 
最強のセキュリティでIoTを実装する方法
最強のセキュリティでIoTを実装する方法最強のセキュリティでIoTを実装する方法
最強のセキュリティでIoTを実装する方法
 
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例
JAWS UG TOHOKU 秋田支部 | IoT 通信プラットフォーム SORACOM 仕組みとサービス& IoT 最新事例
 
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川 日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川
日経ITpro EXPO2015 ソラコム特別講演: IoTのキャズムを超える by CEO玉川
 
SORACOM Dev Conf #0: 新機能発表!
SORACOM Dev Conf #0: 新機能発表!SORACOM Dev Conf #0: 新機能発表!
SORACOM Dev Conf #0: 新機能発表!
 

Similaire à Unowned / Weak References with Closure

React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Nextdynamis
 
Active Object
Active ObjectActive Object
Active Objecty-uti
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & ListenersTaisuke Oe
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】株式会社ランチェスター
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patternsnekop
 
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法Yoshifumi Kawai
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsYoshimasa Tanabe
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaYuta Kawadai
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGParsfumokmm
 
仕事でも Groovy を使おう!
仕事でも Groovy を使おう!仕事でも Groovy を使おう!
仕事でも Groovy を使おう!Oda Shinsuke
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaKazuhiro Sera
 
Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Masakazu Muraoka
 
SPL fukuokaphp_1
SPL fukuokaphp_1SPL fukuokaphp_1
SPL fukuokaphp_1ichikaway
 
JavaScript基礎勉強会
JavaScript基礎勉強会JavaScript基礎勉強会
JavaScript基礎勉強会大樹 小倉
 

Similaire à Unowned / Weak References with Closure (20)

React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
Active Object
Active ObjectActive Object
Active Object
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & Listeners
 
Scope Exit
Scope ExitScope Exit
Scope Exit
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patterns
 
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
 
Dakota+openFoam1
Dakota+openFoam1Dakota+openFoam1
Dakota+openFoam1
 
Leiningen超速入門
Leiningen超速入門Leiningen超速入門
Leiningen超速入門
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE Apps
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for Java
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGPars
 
仕事でも Groovy を使おう!
仕事でも Groovy を使おう!仕事でも Groovy を使おう!
仕事でも Groovy を使おう!
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話
 
SPL fukuokaphp_1
SPL fukuokaphp_1SPL fukuokaphp_1
SPL fukuokaphp_1
 
JavaScript基礎勉強会
JavaScript基礎勉強会JavaScript基礎勉強会
JavaScript基礎勉強会
 

Unowned / Weak References with Closure