Xcode & Objective-C で困るところとか
今の会社に入ってから iOS 開発をやりはじめて、思った所など。
文字列でいろいろ識別するのが嫌だ
なんで Xcode & Objective-C って色々文字列でやらせようとするのだろう。 いろんな識別子を文字列で扱われるとリファクタリング機能で名前変更できないとか、定義元にジャンプみたいな機能が使えないとか、片方変更したのに実行時エラーが出るまで警告も何も出ないから気づけないとか、もう散々だと思う。不満。
例えば
Storyboard ID
- Storyboard上 である ViewController に ID "MyViewController" を設定した場合、コードからその ID を参照するときは文字列(NSString)を使う(@"MyViewController")。
- ↑の @"MyViewController" は型情報じゃないから、当然 IDE の Rename 機能で名前の変更とかできないし、仮にコマンドでコード上では一斉置換しても Storyboard 側は追従されない。変更漏れがあってもビルドエラーにもならない。
つまり実行時まで気づけ無いので死。 - せいぜい「Storyboard ID には ViewController のクラス名をそのまま設定する」ルールにして、コード上では @"MyViewController" とベタ書きするんじゃなくて NSStringFromClass([MyViewController class]) とするくらいしか症状緩和できないと思うのだけど、なんか他にいい方法があるのだろうか…。
- ↑の @"MyViewController" は型情報じゃないから、当然 IDE の Rename 機能で名前の変更とかできないし、仮にコマンドでコード上では一斉置換しても Storyboard 側は追従されない。変更漏れがあってもビルドエラーにもならない。
Segue
Storyboard で Segue の名前 "next" を設定した場合、コードからは文字列(NSString)で Segue の名前 @"next" を指定して参照する。
- だいたい Storyboard ID と同じ点が不満である。
あと、文字列でどうこうという話と関係ないけど、 Segue を使った画面遷移をするとき次の ViewController を初期化する方法も気持ち悪い。
prepareForSegue:sender: の中で次の画面の ViewController インスタンスを取り出して property に値をセットするのだが、つまり property を public に readwrite な状態にしておかなければならないわけで、嫌だ。
後から書き換えたい妥当な理由がない限り、 readonly にしておきたい。つまり普通に Factory 代わりの自作コンビニエンスコンストラクタを経由して引数を渡しながらインスタンス生成出来たほうがマシだ。
NSNotificationCenter の通知名
- 通知名は文字列で扱う。
- 通知名には定数を定義して使おうというのが正攻法だとは思う。たとえば UIKit で用意されている UIKeyboardWillShowNotification みたいな。
- が、全ての通知名は同じ名前空間に存在するため、重複しないよう自分で管理しなければいけない。
- これについては NSNotificationCenter をラップして Observer パターンを実現するクラスを用途ごとに作ればよさそう、と思ってそうしているので、気が向いたらそのうち書く。
NSUserDefaults の key
- KVS なので key が文字列なのは仕方ないがやはり重複しないよう開発者が気をつけなければいけないのは困る。
- やはりこれもラップクラスを作るのがいいと思う。
- CocoaPods にもいくつか Utility 的なライブラリがある。
- アプリのアップデート時、key の設計を変えていないか注意が必要な点が NSNotificationCenter より厄介。
記述が冗長なのが嫌だ
全体的に冗長の極みだと思うけど、特に使っていて面倒なのが UIAlertView と UIActionSheet であった。
UIAlertView
愚直に使うとこんな感じ。
- ボタンの定義とイベントの処理部分が離れていて読みづらい書きづらい
- その都度 UIAlertView の Delegate 専用クラスを他で用意するならこれでもいいのだけど、なんだかんだ言って alertView.delegate = self; することは多い
- 要するにこう書きたい
- で実際そう書けるようにして使っていたのだけど、みんな同じこと考えてる系だったし、Blockskitとか使ってもいい感じにできることを後から知った。
UIActionSheet
大体言いたいことは UIAlertView と一緒で、↓こう書けるようにして使ってる。
やっぱり Blockskit 使うと同じようなことができる。
その他
まだいくつかあるので気が向いたら書こうと思う。
Abstractクラスがないとか(クラスベースでやるなら欲しい)。
動的型付けだとか。
メソッド名長すぎとか。
名前空間ないとか。
物理ディレクトリとXcode上のグループが同期しにくいとか。
クラス名・メソッド名にプレフィックスつけるとか。
iOS7 ではすりガラスがいいんだ!といっときながらリアルタイムな blur がかけられる API が提供されないとか。