プログラミング 美徳の不幸

Ruby, Rails, JavaScriptなどのプログラミングまとめ、解説、備忘録。

2ヶ月ほど書いた知見

最近このブログがエンジニアブログっぽくないので、今日は久々に技術の話を。

最近iOSをやっていて、まぁメモリ管理・スレッド管理が重要なクライアントアプリを初めて作っているのでなかなか手こずっている。手こずっているんですが、少しずつ勘所はつかめてきて、いい感じになっています(適当)。

iOSRailsよりは規約が少ないので、逆に設計がモノを言ってくる印象があります。
で、ある程度やった中で、知見がなんとなく固まりだしたのでそれを備忘録的にまとめたい。

まず今storyboardを使っていて、フォントの変更とか色の変更にうんざりするコードを書く必要がないのでそれはそれで助かっています。しかしstoryboardにも嫌な点は(開発2ヶ月目にして)すでにたくさん出てきています。
いくつかあげるとこういうところです。

1. コンテクストスイッチが発生する(コードとstoryboardの行き来がだるい)
2. 実行時エラーが多発する(Storyboard上のidが実行するまで存在するかわからない)
3. 単にstoryboardではサポートされていないということがある (storyboardをまたぐsegueの設定、あまり一般的でないviewのつくりなど=navigationbarのタイトルを画像にするとか)
4. 期待している挙動と違うことがある ・・・(※)

※に関しては、あるボタンをタップしたときに下からドラムロールを出すという実装をしようと思ったときに、ドラムロール用のviewcontrollerを作成してstoryboardで下部にドラムロール、上部に透明なviewを配置し、modal segueで上に重ねた時、期待している挙動としてはドラムロールが下から出現して上半分はそのままもとのviewが見えてるようなイメージだったけど、実際はviewcontrollerが出終わったあとにもとのviewcontrollerのviewが消滅してしまいました。

これはつまりsegue実行後に一時的にメモリを開放して、modalを閉じた時にもう一度復元するという処理をやってくれているようです。このときのドラムロールの実装では意図した挙動と違ったのでsegueは採用できなかったんですが、逆に言えばプログラマが管理していない部分でパフォーマンス的な向上をやってくれているのかもしれません。

デメリットも多い一方で、個人的な思想として見た目のようなものをコードで書くのは全時代的だという発想があるので、storyboardは今後も使っていくつもりです。



あとは、namespaceがないので命名規約をプロジェクトごとにはっきりさせるのが非常に重要だと思いました。xcodeリファクタリング機能があるからといって、意外とソースのディレクトリを切り直したりするとめんどくさいです。


で、それとcocoa frameworkは非常にオブジェクト指向的に厳格なフレームワークだと感じました。例えばUIAlertViewを実装してボタンが押された際のdelegateをそのviewcontrollerにしたりすると、同じviewcontrollerで別のUIAlertViewを作成して同じくdelegateを指定したいときに困ったことになります。
これはひとつのviewcontrollerにtableviewを複数作成する際とかにも同じことが言えると思いますが、最悪なのは同じprotocol methodにif文を書くことかと思います。

これがベストプラクティスかはわからないですが、ひとまずuialertviewに対応するdelegateをそれぞれクラスとして用意することにしました。

@implementation MyRequireLoginAlertViewDelegate {
    __weak MyRootViewController *controller;
}

+ (id)newWithController:(MyRootViewController *)controller
{
    id s = [[self alloc] initWithController:controller];
    return s;
}

- (id) initWithController:(MyRootViewController *)con
{
    self = [super init];
    if(self)  controller = con;
    return self;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [controller popupLoginViewController];
}
@end

これはこれでcontrollerの実装と密結合になっていてあまり良くないとは思うのだが、(このcontrollerとかもさらにdelegateにすべきなのだろうか)、まぁひとまずif文地獄にはならないで済んだ。

その他にもHTTPRequest用のクラスとか、データソースによらずにデータとviewを接続するクラスなど、抽象化すべきところは抽象化すべきなんだろうなと感じている。

詳しいことはまた次回に。