今回からは再び本編に戻って 無所有参照
を 暗黙アンラップされるオプショナル
と併用する話のサンプルコードの解説的なところを眺めていきます。循環参照
を解消するための手法としてのサンプルなのでそんなあたりを気にしながら、これまでの雑談も含めた復習気分でコードを確認していきましょう。どうぞよろしくお願いしますね。
————————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #251
00:00 開始 00:11 今回は強参照循環の話 01:10 これまでのおさらい 02:15 暗黙アンラップなオプショナル型の主張 03:43 暗黙アンラップなオプショナル型と無所有参照による循環参照解消策 04:22 無所有参照が開放されたときに注意 05:23 もう片側に unowned を付けたとすると? 07:37 循環参照の解消例についての解説 08:45 二段階初期化 12:07 暗黙アンラップなオプショナル型の美しさと心配どころ 13:45 たくさんの知識的要素の詰まった場所 15:31 カスタマイズフェーズの考え方 18:15 今回の循環参照解消例のまとめ 21:29 機能ひとつひとつの特徴を捉えて、適する場面で活用していく 23:16 クロージングと次回の展望 —————————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #251
では、勉強会を始めていきましょう。今日は久しぶりに本編に戻りまして、循環参照の解決についてお話しします。特にクラスインスタンス版における循環参照の問題です。皆さんも忘れているかもしれませんが、この辺りの内容を再度見ていこうと思います。
現在、無償強参照とオプショナルの組み合わせについて見ていましたね。今回のテーマは、「無償強参照」と「暗黙的にアンラップされるオプショナル」を組み合わせた場合の話です。
復習ばかりだと前に進まないので、ざっくりと復習しておきます。以前の例としては、アパートメントの話とか、入居者と物件の話がありましたね。他にも、デバスタマトページの話などです。
具体的な例として、背景を少し変更して循環参照を解消する例に移ります。また、今回は無償強参照に加えて、暗黙的にアンラップされるオプショナルを組み合わせて解消する例について説明します。例として「国」と「都市」が出てきます。国は都市を持ち、すべての都市は国に所属する、というモデルです。この例が、循環参照を解消する手法として紹介されています。
確認しておきますと、国は都市を持つけれど、初期化の都合で「暗黙的にアンラップされるオプショナル」が使われる場合もあります。この場合、利用者に対して「代(値)が存在しています」と保証する形で提供します。オプショナル型を安心して使いましょうというメッセージが添えられていますが、提供する側も安心して使用できるように、しっかりとした提供を行いましょう。
もちろん、時にはその枠を越える必要が出てくる場合もあります。前回も話しましたが、どうやって安全性を担保するか、特にイニシャライザーを超えるような期間やフェーズが必要な場合についての考慮も必要です。そのような場合、利用する側が盲目的に安心して使えるとは限りませんね。
したがって、安全で適切な手続きを踏んでから使用するべきだ、という主張もできるでしょう。そういうわけで、今日の内容をしっかり学んでいきましょう。 とりあえず、これを併用した順番解消策として、併用とは言ったけれども同時にはならないということですね。こちらは無所有参照で、次の例のシティの方で暗黙的にアンラップを使っています。状況によっては併用することもあり得ますが、オプショナル型に暗黙的にアンラップを組み合わせる際には注意が必要です。特に保持するところがなくなると解放される可能性があるので、その辺りを考慮する必要があります。
暗黙的にアンラップされるオプショナル型がすぐに解放されるような状況は、バランスが良くないことが予想されます。例えば、暗黙的にアンラップされたオプショナル型が長い期間生存する場合、シティの方がグローバルなクラスで、そこに暗黙的にアンラップされたプロパティが存在するというような状況も考えられます。
こうした場合、プロパティをイニシャライズする際にオプショナルが不要になるかもしれません。それについては、適切なところに落ち着かせることが必要ですが、オプショナルを使わずに済む場合もあるでしょう。ただ、追求しなくても、順番を考えた解決策が例として続くという可能性が高いです。
シティとアンドリーの相互依存性を設定するため、要するに順番を定義するために、シティのイニシャライザーはアンドリーを受け取りプロパティに格納するインターフェースになっています。シティのイニシャライザーはアンドリーから呼び出されるように設計されています。以前の勉強会でも話しましたが、このイニシャライザーをファイルプライベートやローカルにしておく選択肢もあります。
トゥフェイズイニシャライゼーションについて、新しいカントリーのインスタンスが完全に初期化されるまではセルフをTに渡すことができないため、暗黙的にアンラップされたオプショナルを使用しているということでした。トゥフェイズイニシャライゼーションは、初期化フェイズとカスタマイズフェイズの二つのフェイズで構成されており、特にクラスのオーバーライドの際によく出てきます。
初期化フェイズでは全ての保存型プロパティが初期化されるまでセルフを使用できませんが、初期化が完了するとカスタマイズフェイズに移り、セルフが参照可能となり、初期化済みのプロパティを変更できるようになります。この二つのフェイズを利用して、安全かつ確実に初期化を進めていくことができるわけです。 わかりにくいところや質問があれば、どんどん聞いてください。脱線してでも答えますからね。それでは、とりあえずこれくらいにしておきます。気になる方は、後で初期化フェイズやカスタマイズフェイズについて、オープンハンドブックを検索すると何話か出てくると思いますので、アーカイブを引っ張ってきて確認してみてください。
さっきの初期化フェイズの話ですが、オプショナルを使うことによって、適定値で nil
を持ち、つまり初期化フェイズを nil
で完了させられます。そして、その後カスタマイズフェイズでカントリーをカスタマイズしていくという流れになります。それでありながら、暗黙的にアンラップされるオプショナルなので、使うときにわざわざ !
を使わなくても自動的にアンラップしてくれます。そのため、コードの書き心地も向上し、可読性も向上します。プログラマーが考えることが少なくて済むという利点もあります。
この説明だけを見ると、全体的に見て素晴らしい折り合いの付け方をしていると感じます。しかし、よくある話ですが、暗黙的にアンラップされるオプショナルだと、宣言するときに無理を感じることがあります。ここを避けたいという感覚もあるでしょう。実際にその感覚は正しいことだと思いますが、今の解説で見たとおり、全体としてはとても良い感じに辻褄を合わせていて、「きれいだ」と捉えることができます。
この方法で自信を持ってコードを書けるとしたら、理想的ですし、プログラマーのレベルとしても初級者から中級者、上級者へとステップアップできるでしょう。こういう些細な短いコードにも、いろんなことが詰まっていますね。
ここで共通しているのは、アンラップやイニシャライザーの責務が何かということです。特に、デジグネイティブイニシャライザーについてはまた詳しく説明します。 このセクションでは、初級者向けの基本フェーズとカスタマイズフェーズについて説明しました。さらに、このイニシャライザーが外部からアクセス可能であるべきか、内部でのみ呼び出されるのが適切かによって、アクセスコントロールを設定する方法にも触れました。
一般的な質問としては、クラスが適切かどうか、ストラクトにすることで循環定義が発生しないか、クラスのままで問題ないなら循環参照を解消する方法を考えるなどがあります。
次に「トゥーフェイズイニシャライザー」の説明に移りました。これは、イニシャライザーがネーム化設定された時点で完全に初期化され、その後はカスタマイズフェーズに移行することができるものです。この方法により、セルフを参照したり他のインスタンスメソッドやプロパティを使用することができるようになります。
セルフの参照が可能になると、初期化の中でプロパティを設定するだけでなく、初期化の手続きをカスタマイズすることも可能です。初期化用のメソッドを用意する場合には、インスタンスメソッドとして用意するか、タクティックなメソッドとして用意するかを考える必要があります。
例として、ハントリーのイニシャライザーについて考えてみましょう。これは、自分のキャピタルシティを設定する際に、シティのイニシャライザーの引数としてハントリーを渡すことができます。一行で初期化し、中でシティを作るという方法が役に立つかは状況により異なりますが、サンプルとしてはこういった方法もあるということです。
今回使用した例としては、オプショナルを使って二段階クラス初期化(トゥーフェイズイニシャライザー)を実現しました。この方法により、初期化が終わった後も循環参照を回避しながらオプショナルではない値として扱うことができるようになります。
まとめると、ウィーク参照やアンラップされたオプショナルのオプションを使い分けることで、インスタンス間の共産主要循環の回避策を検討しました。ただし、これらの技術を使いこなすためには、その特徴を理解し、状況に応じた適切な判断が求められます。
次回のテーマは、クロージャーが関係する共産主要循環についてです。このあたりをしっかりと理解し、共産主要循環を回避する対策を見ていこうと思います。お疲れ様でした。ありがとうございました。