サンプル勉強会 1-1 ソースコードリーディング
はじめに
前回お話ししたiPhoneアプリのサンプル集を用いた勉強会について記します。今回は、シンプルでコード量の少なそうなForceSketchを題材にソースコードリーディングをします。
勉強会の進め方
ソースコードリーディングフェーズ(1h)と共有フェーズ(0.5h)の次回配分で進めます。各フェーズで行うことは下記の通りです。
- ソースコードリーディングフェーズ
- 下記の項目を意識して読む
- 実装のキモ
- いいねっていう実装
- 微妙だと思う実装
- 知らなかったという実装
- 下記の項目を意識して読む
- 共有フェーズ
- ソースコードリーディングでまとめたものを共有
結果
今回のサンプルは、swiftのバージョンが古かったため、動かしながら確認ができず、皆苦戦していた。適当にサンプル集のgifだけで選んでしまったのがよくなかった。
ただ、ViewController.swiftのみで完結しているので、初めての試みとしてはちょうどよかった。自分で実装するときにどう分離するかという練習にできそうなので。
他のメンバーの共有フェーズ時の議論内容
- 15行目などの
!
(暗黙的アンラップ型:Implicitly Unwrapped Optional)ってどうなの?- 固定の引数のため一度動作確認取れていれば動くということか?
- 仮に、この絶対性がなかったとしてもサンプルということで、アプリが落ちればいいだけとも考えられる
- インスタンス利用時に必ず初期化されることが保証できる場合なら使うと便利らしい
- 固定の引数のため一度動作確認取れていれば動くということか?
- 54行目の
UIEvent?
でなぜ?(オプショナル型)- UIKitの仕様
- 昔からの名残があるんじゃないかな?
- 56行目のような
guard
の使い方いいね - 75行目の
coalescedTouch.force != 0
の意味がぱっと見でわかりにくい- extensionでメソッド作るといいかも
- 75行目の三項演算子が長くてわかりにくい
touchesEnded(_:with:)
だけでなくtouchesCancelled(_:with:)
も実装したほうがいいのでは?- ちゃんとしたアプリであれば、仕様の検討したほうがいい
- 51行目などの
touches.first?
は、このスコープではtouchって絶対あるのだろうから?
じゃないのでは?Set
クラスの仕様- 空だったらnilが返ってくる
step()
の使われ方がよくわからない- CADisplayLinkでUnityのUpdate()みたいなことしてるだけ
- "CADisplayLinkは画面のリフレッシュレートと同期して描画させるタイマーオブジェクトです。"
- CADisplayLinkでUnityのUpdate()みたいなことしてるだけ
私の共有フェーズ時の議論内容
実装のキモ
locationInView(view)
で画面(UIViewControllerのview)での座標を掴んでるlet lineWidth = coalescedTouch.force != 0 ? (coalescedTouch.force / coalescedTouch.maximumPossibleForce) * 20 :10
で圧力から線の太さ決めているのだろうimageView.image = UIImage(CIImage: imageAccumulator.image())
- CIImageは忘れたが、UIImageに変換できて、CIFilterとかは画像処理になるんだろうな。直接画像をプログラムで処理してるんだろう
CADisplayLink
でUnityのUpdateみたいになるんだろう
知らなかったもの
- 画像処理系(昔使ったけど忘れたやつ)
- CIFilter
- CIImageAccumulator
- UIGraphicsBeginImageContext
- UIGraphicsGetCurrentContext
- CGContextSetLineCap
- その他(初めて見た)
- CADisplayLink
- coalescedTouchesForTouch
問題点
- IB使ってない
let imageView = UIImageView()
- autolayoutをちゃんと使ったほうがいい
- let lineWidth = coalescedTouch.force != 0 ? (coalescedTouch.force / coalescedTouch.maximumPossibleForce) * 20 :10
- マジックナンバーたくさんでわかりにくい
- classに分離したい
- CIFilleterのname引数に文字列指定がタイポとか怖い
その他
- 描画処理系で、Begin, Endで囲むというのはよくみる気がする。
- CGContextRef型のcgContextを取得し、それを関数の引数に渡して実行する感じがc言語っぽさを感じる
終わりに
今回は、ForceSketchを題材にソースコードリーディングをした際に、皆で議論した内容を記しました。一部、推測で書いている部分もあるため、間違っている情報もあるかもしれません。もしご存知の方がいらしたらご指摘いただけたら幸いです。
次回は、今回のソースコードリーディングを元に自身らで実装します。