寄付窓口はこちら

try! Swift Swiftヒップスター #tryswiftconf Day3-4

Hector Matos

素晴らしい州であるテキサスでラマによって育てられ、ゼルダの伝説をしたり、Game of Thronesを見ながらテレビの前で叫んだりするカウチポテトとして成長しました。家では座ってのんびり過ごさず、KrakenDev.ioでブログを書いている一方、Capital Oneのオフィスではデスクに座ってiOSAndroidのモバイルアプリの開発をしています。モバイルのUI/UXに強いこだわりをもっており、彼の書くコードは世界をよくしています。Boris, ya tu sabes.

twitter.com

Swiftにはあまり知られていない多くの細かい機能があります。それを知っていれば開発にかかる時間や労力を削減することができます。少しの重要な機能を覚えるだけです。この講演では、Swiftのあまり見慣れない機能を多数、初心者にも分かりやすいように解説します。講演後は、日々の開発中に出くわす見慣れない構文を、一目で解読できるようになっていることでしょう!

資料

ご本人によるブログ記事が公開されています。

krakendev.io

そしてその日本語訳が @takecian さんによって公開されています。

qiita.com

本編ここから

こんにちは孫悟空です。(仮装している)

これらのお話です。

f:id:niwatako:20160304115910j:plain

Swift理解に必要です。日々の作業が楽になります。

私自身何度もこれらを見てきました。でも熟知するのは無理だと思いました。

見てもわからない

f:id:niwatako:20160304115958j:plain

心配しないで下さい、どんどん簡単になります。

f:id:niwatako:20160304120024j:plain

クロージャーが1級市民です。変数になり、メモリに落とし込まれます。クロージャーを関数に渡すことを忘れて何処に格納したか忘れて使えなくなることがある。

f:id:niwatako:20160304120118j:plain

これを渡すが、べつのArrayに格納されて、NotificationnameをKeyにする。

NotificationCenterはブロックを割り当ててクロージャー関数をエスケープしてくれる。

エスケープしてしまっているということを覚えておいて下さい。

それは、そのファンクションの中でコールが出来なかったということになります。

エスケープさせたくなかったらどうしたらいいでしょう?即座に実行したかったら?

f:id:niwatako:20160304120238j:plain

クロージャパラメータに注釈をつけることが出来る。クロージャの前につける。

関数コントロールフローからエスケープさせる

f:id:niwatako:20160304120315j:plain

コンパイラは、何もわたっていません。何も渡せない、これだけでは十分ではありません。エスケープするべきではなクロージャーがエスケープされていると教えてくれる。

noescapeは裏で最適化をしてくれる。自分でnoescapeのなかでエスケープしていないものを自分で探す必要はない。

autoclosuerの話をします。

f:id:niwatako:20160304120435j:plain

f:id:niwatako:20160304120450j:plain

Booleanを渡しているだけ。クロージャーに渡しているわけではない。特別なのはこの点。Nameの段階で全てを理解することが出来る。Noescは引数を自動的にラッピングする。

Noescapeクロージャーをみなさんのために作ってくれる。

ここでみたコードはこれと同じ動きをする

f:id:niwatako:20160304120608j:plain

autoclosureは引数を自動でラップしてくれる。

もっと簡単な話をしましょう。

f:id:niwatako:20160304120641j:plain f:id:niwatako:20160304120651j:plain

こんなのを見たことが有りますか?変数に見えない、大きな関数にしか見えない。ほかのlazy varと混ざるとわからなって大変。

これをこんなふうに表せる。こんなに素晴らしい

f:id:niwatako:20160304120756j:plain f:id:niwatako:20160304120801j:plain

どうやって機能しているのか?Selfがいるじゃん?

f:id:niwatako:20160304120818j:plain

全部背景でやってくれます。居コールサインの右側に入れてラップしてくれます。非常に強くキャプチャするのでこれは警告として出しておきます。使うときは今日参照でSelfキャプチャしますので注意して下さい。

これはよくあるユースケースです。

f:id:niwatako:20160304120906j:plain

f:id:niwatako:20160304121003j:plain

Javaや他の言語も対応しています。

f:id:niwatako:20160304121020j:plain

魔人ブーと悟空の戦いの設定です。馬鹿げたロジックがあって、どこでbreakするか書いています。

ループが長くなるのは馬鹿げています。

f:id:niwatako:20160304121110j:plain

labelループでスッキリ。

これらのループを設定した後、ここで最終的に成功してアタック、だいたい戦い終了までに5個ぐらいのエピソードが有り、ヒーロが決まる。

明示的にプログラムに対してループをbreakする。インナーをブレークしてアウターをブレークしてブーリアンで管理ということをしなくて良いのが利点。

f:id:niwatako:20160304121244j:plain

とても良い機能で見落としがちで、使っていないアプリもありますが、これを使うととてもシンプルにある。

f:id:niwatako:20160304121314j:plain

サイヤジンになったら髪の毛が変わるとか、ヘアカラーの種類がある

f:id:niwatako:20160304121339j:plain

こんなロジックになりますね。

これはSwiftyと言えなくもない。いや、実はそうではありません。Typeオミッションを使わないと。

f:id:niwatako:20160304121419j:plain

静的変数と関数はクラスやValueの中に入っている。可能になった実装を見る。

f:id:niwatako:20160304121510j:plain

パワーレベルを毎回使う時にタイプする必要はない。enumと同じように使えます。

変だと思うかもしれませんが、enumがそもそもこのように機能するのです。

enumの中の静的変数はenumを返してくる、同じことをstatic func でやっている。

static var が enum のように動くなら、タイプを省略できます

f:id:niwatako:20160304121711j:plain

少しの変化だが読みやすいコードが作られる。

コードは本のように自然に読めるべきだと思っている。そうでないなら皆さんに問題があるのではないでしょうか。

f:id:niwatako:20160304121749j:plain

f:id:niwatako:20160304121801j:plain

翻訳してくださったらアップしますので送っていただければと思います。

QA

インライン lazy var の所、聞き間違いかもしれないがautoclosureと同じようにラップしてくれるということだったと思うが、selfを強くキャプチャするという話があって、autoclosureとは違うものなのでしょうか

autoclosure と inline lazy var の違い、有ります。inline lazy varはautoのように振る舞うがautoではない。selfをデフォルトストロングキャプチャはそうです。振る舞い自体は同じだが違うのは確か。

self.methodと書いてあったがキャプチャされていないのか、自分で自分をキャプチャすることにはなっていませんか?

f:id:niwatako:20160304122100j:plain

これは明白には見えない、それだけ強くキャプチャされていることは見てわからない。でもデフォルトですごく強く参照するということを警告しました。inline lazy var の悪い点です、コードを読む人がわからないんです。

多くのlazy var が重なるときは読みやすくなるので、そういう時だけ使って下さい。

gist.github.com

noescapeやlazyのワードが並んでいたスライドで、

f:id:niwatako:20160304122304j:plain

lazier はなんでしょう

タイプミスです。inline lazy var と書きたかった。

両方ラベル付けする意味は?

f:id:niwatako:20160304122446j:plain

複数のレベルをネスト化出来ることをお見せしたかった。

autoclosureですが、使うと、連携するクロージャーを設定できるでしょうか。それとautoclosureを入れないほうがいい場合があるか

f:id:niwatako:20160304122621j:plain

ほとんど使えると思うが、書いてるコードにもよるかと思う。Appleはコード全体であまり使わないようにと言っている。読みやすさが下がってしまう。アサートが何をしているかわからない。

私の日々の仕事としては、このautoclosureはあまりよいユースケースは、パッとは出てきません。

気に入った記事は はてなブックマーク

はてなブックマークアプリiOS開発チームから来ました! はてなブックマークにはSwift特集があります! 良い記事を見逃さないように、ご利用ください! http://b.hatena.ne.jp/hotentry/it/Swift

そして良いまとめ記事があったらはてなブックマークでブックマークしましょう! try! Swift の記事で盛り上がると嬉しいです!