viewDidUnloadって呼ばれるの?

2つ目のiOSアプリケーション:ストーリーボードを読んでいて以下のような一文を見つけました。

viewDidUnloadメソッドは、ビューに強い参照がある場合に、そのクリーンアップ処理を実装するべき箇所です。
このチュートリアルでは、詳細コントローラのビューが、“Detail View Controllerのヘッダファイルをカスタマイズするには、以下の手順を実行します。”(46ページ)で作成した、sightingプロパティの強い参照を保持しています。viewDidUnloadメソッドを編集して、sightingプロパティに対する強い参照を解除するようにします。

これを見てクリーンアップを実行すべき、というのが分かったのですが。そもそもviewDidUnloadメソッドとは何なのだろうと思いました。

そこで xcode上で Commandキーを押しながら関数名をクリックして宣言を見てみました。すると UIViewController.h が表示されます。

- (void)viewDidUnload NS_DEPRECATED_IOS(3_0,6_0); // Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc.

このコメント部分をみて、ビューがリリースされた後で呼ばれるとありますがそれは何時なのだろうと疑問に思いました。そこで次は、iOS View Controllerプログラミングガイドを見てみました。
viewDidUnloadというキーワードでドキュメント内を検索すると、一件だけ検索結果があります。P68の「メモリが不足しそうなとき、システムがビューをアンロードすることがある(iOS 5以前)」という部分ですが。この部分を読んでみると、どうもアンロードサイクルというものがあるようです。図 4-3 にそれが示されています。viewDidUnload の前に viewWillUnload なんてものもあるんですね。そしてデフォルトで実装されていた didReceiveMemoryWarning も図には記載されています。図のおかけでメソッドの呼ばれるロジックが理解出来ました。

実際によばれるところを確認したいとおもい、新しい Master-Detail Application を作成してみました。DetailViewController.m にメソッドを追加してアプリを実行してみました。

- (void)viewDidUnload
{
    NSLog(@"viewDidUnload");
    [super viewDidUnload];
}

- (void)viewWillUnload
{
    NSLog(@"viewWillUnload");
    [super viewWillUnload];
}

しかし、起動したアプリ内で追加ボタンからの新規データの追加、詳細ページへの遷移、一覧ページでのレコードの削除、などなど色々操作をおこなってみましたが、まったくログが出力されることはありませんでした。結局ビューが削除されるタイミングというのを見ることはできず、残念な結果となってしまいました。何か実装を間違えたのかもしれませんが、、、

ただしチュートリアルに記載されている通り、クリーンアップ処理の実装には気をつけていきたいと思います。

アプリケーションデリゲートでは多数のタスクを実行しない?

2つ目のiOSアプリケーション:ストーリーボードを読んでいて以下のような一文を見つけました。

アプリケーションデリゲートで多数のタスクを実行することはできる限り避けて、代わりにView Controllerにより多くの責任を与えるようにすべきです。

これはどいういう意味なのでしょうか。この内容を理解するためにまずはアプリケーションデリゲートとView Controllerについて調べてみました。

iOSアプリケーションプログラミングガイド 表 2-1

アプリケーションデリゲートは、アプリケーションの起動時に、一般にUIApplicationMain関数で生成するカスタムオブジェクトです。このオブジェクトの主な仕事は、アプリケーションの状態遷移を制御することです。起動時の初期化や、バックグラウンドとフォアグラウンドの状態遷移に伴う制御を行います。アプリケーションデリゲートを用いて状態遷移を管理する方法について詳しくは、“アプリケーションの状態変化の管理” (36 ページ)を参照してください。
iOS5以降、アプリケーションデリゲートを使って、ほかのイベントも処理できるようになりました。Xcodeのプロジェクトテンプレートでは、アプリケーションデリゲートをUIResponderのサブクラスとして宣言しています。UIApplicationオブジェクト自身がイベントを処理しない場合は、アプリケーションデリゲートに振り分ける(ディスパッチ)ようになっています。処理できるイベントのタイプについては『UIResponderClassReference』を参照してください。

そしてView Controllerオブジェクトについても下記のように記載されています。

View Controllerオブジェクトは、アプリケーションのコンテンツの画面表示を管理します。特定のビューだけでなく、そのサブビューのコレクションも管理します。アプリケーションのウインドウ上に各ビューを埋め込んで、目に見える形にする役割があります。

詳しくはiOS View Controllerプログラミングガイドの1章を読むのが良さそうです。

疑問の回答となる文章を見つける事はできませんでしたが、上記の説明を読んで自分なりに考えてみました。
アプリケーションデリゲートは、UIApplicationオブジェクトが処理しないイベントを受け付けるようになっています。そのため、アプリケーションデリゲートに様々なな処理を記述してしまうと一つのクラスが肥大化してしまうのではないでしょうか。そこで処理をView Controllerに委譲してしまうことを推奨しているのではないかと思いました。View Controllerはアプリケーションのデータと外観を管理するための存在であるため、処理を委譲されることは役割的にもあっているように思えます。

今後の開発では、「アプリケーションデリゲートでは多数のタスクを実行しない、View Controllerに任せる」でいきたいと思います。

cellForRowAtIndexPath が呼ばれるタイミングとは?

2つ目のiOSアプリケーション:ストーリーボードを読み進めている中で、P41 に以下のような記述を見つけました。

TableViewオブジェクトは、テーブルの行を表示する必要が生じるたびに cellForRowAtIndexPathメソッドを呼び出します。

そこで実際にこのメソッドが呼ばれるタイミングは何時なのか気になりました。日本語ドキュメントの一覧を眺めてみるとiOS Table Viewプログラミングガイドというドキュメントがありましたので、少し読んでみました。
cellForRowAtIndexPathというキーワードで pdf内を検索してみると、いくつか情報が見つかりました。P48 に以下のような記述があります。

次に、tableView:cellForRowAtIndexPath:メソッドを繰り返し呼び出して、表示する各行のセルオブジェクトを取得します。Table Viewは、このUITableViewCellオブジェクトを使用して、その行のコンテンツを描画します(Table Viewがスクロールされた場合にも、新たに表示する行に対してtableView:cellForRowAtIndexPath:が呼び出されます)。

ここには、スクロールされた場合もメソッドが呼び出されるという事が記載されています。どんな風に処理されるのか気になったので、シンプルな Master-Detailアプリを作ってtableView:cellForRowAtIndexPath:にログを仕込んでみることにしました。

NSLog(@"row: %d, count: %d", indexPath.row, [_objects count]);

アプリを動かしてADDボタンを押してみると、メソッドが呼ばれているのがログ出力でわかります。

2013-03-29 02:59:48.819 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 1

続いてADDボタンを連打して画面をデータ埋めてみました。

2013-03-29 02:59:49.380 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 2
2013-03-29 02:59:49.901 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 3
2013-03-29 02:59:50.375 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 4
2013-03-29 02:59:50.815 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 5
2013-03-29 02:59:51.250 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 6
2013-03-29 02:59:51.707 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 7
2013-03-29 02:59:52.180 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 8
2013-03-29 02:59:52.710 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 9
2013-03-29 02:59:53.238 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 10

その後上下に画面をスクロールすると面白いログ出力がおこなわれました。
下にスクロール

2013-03-29 02:59:56.550 TrialCellForRowAtIndexPath[53532:c07] row: 1, count: 10
2013-03-29 02:59:56.701 TrialCellForRowAtIndexPath[53532:c07] row: 0, count: 10

上にスクロール

2013-03-29 03:00:07.474 TrialCellForRowAtIndexPath[53532:c07] row: 8, count: 10
2013-03-29 03:00:07.592 TrialCellForRowAtIndexPath[53532:c07] row: 9, count: 10

画面内にセルが入るタイミングでメソッドが呼ばれているのがわかります。一度描画したものは保存されているのかと思っていましたが、そうではないようです。この辺りは描画に関するロジックの理解が必要なのかもしれません。

結論

ドキュメント記載されている通りでした。表示するセルができるたびにメソッドは呼ばれていました。

"初めてのiOSアプリケーション" を読んで

Apple が提供している日本語ドキュメント、初めてのiOSアプリケーションを読んだ感想です。

こちら初心者向けのチュートリアルとして用意されているドキュメントで、3つあるチュートリアルの初めの一巻です。ざっくりまとめると以下のような感じでした。

  • まずは xcode に触れる
  • xcode の画面の項目をおぼえる
  • StoryBoard での開発を体験する

ボリューム的には大したことはありません。すぐに終わってしまうようなボリュームです。しかしまずは体験する、という目的では良いドキュメントであると思います。次のチュートリアルの前座といった感じでしょうか。こちら読み終えたら以下のチュートリアルに進むべきだと思います。
2つ目のiOSアプリケーション:ストーリーボード

iOSアプリ開発の事始め

今更ながら iOSアプリを開発しはじめようと思いました。入門書を買って読んだりしましたが、いまいちいっくりこなかったため、ネットで色々と調べました。探しているうちに Apple のドキュメントがあることを知りました。以下は自分が調べたことメモです。

一応自分はシステムエンジニアであり、プログラミング経験者です。そのためプログラミングの勉強というよりもアプリ開発を目的として調べました。

まずは写経からということで、以下の3つを選びました。StoryBoard を使った最新の実装方法で記述されているため、特に引っかかることもなく進めることができました。

その他補助的なドキュメントとして以下のものも合わせて読みました。

  • Objective-Cプログラミングの概念
    • アプリ実装の概念について学ぶことができました。しかしこのドキュメントはプログラミング経験がある程度ないと理解しずらい気がしました。
  • Objective-Cプログラミング言語
    • プログラミング言語的なところはこのドキュメントを読んで補足するようにしました。ただし説明があるだけで写経する部分はないため、プログラミング初心者はやはり写経できる別ドキュメントがあった方がいいようにも感じました。リファレンスとして見るにはよいレベルのドキュメントだと思います。

まだまだ写経が正直足りない気もしているため、英語サイトのドキュメントも探してサンプルコードを見つけようかとも思っています。よさそうなドキュメントが見つかりましたら、別途ブログにあげようかと思います。

最近の micro SD 事情とは?

かなり久しぶりにブログ更新です。久しぶりなのであっさりした内容で。

kobo のデータストレージ用に micro SD を購入しようと思ったのですが、micro SD がデータストレージの一種であること以外に全く理解できていなかったので、ちょっと調べてみました。

まずは、wikipedia
http://ja.wikipedia.org/wiki/SD%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%BC%E3%82%AB%E3%83%BC%E3%83%89

次に価格.com
http://kakaku.com/camera/sd-card/
http://kakaku.com/camera/sd-card/ma_0/s1=3/

micro SD にはハイスピード版である、SDHC というものあるようですね。
kobo は microSDHC(最大約32GB) 対応のようなので、価格的にみ合えば購入するならこっちそうです。

で、考えるべきは「容量」と「スピード」でしょうか。

容量は1G辺の単価が非常に安くなっているので、できるだけ大きな容量にしておいた方がよさそうな感じですね。
スピードに関しては、CLASSというデータ転送速度の目安が設けられているので、こちらを見るのがよさそうです。CLASS10が一番早いようですが、「※ Class10は後で規格化されたため、ハードによっては上位互換がない。」という記載が少々気になるところではあります。Amazonで調べてみると、各社CLASS10のものを販売しているようですので、現在ではそこまできにする必要はなさそうですね。

自分は結局これをぽちっとしました。
http://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%91%E3%83%AF%E3%83%BC-SDHC%E3%82%AB%E3%83%BC%E3%83%89-Class10-SDHC%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF%E3%83%BC%E4%BB%98-SP032GBSTH010V10-SP/dp/B007T5EUX2/

まだ手元に来てないので、すいませんがレビューはなしで。
使ってみての感想ですが、特に問題なしです。
また、自分は MacBookAir を使用しているのですが、付属しているアダプターがそのまま使えたため別途購入せずにすんだのも非常に助かりました。

Macでのキーボード操作

以下にMacでのキーボード操作を記録します。
これらの操作を覚えたことで入力のスピードが上がったように思います。理由としては、ホームポジションから手の配置を移動させる事が少なくなったためです。
また、ホームポジションから手を移動させる必要が少なくなったため、移動のストレスがかなりなくなりました。ただし、以下の操作には多少慣れが必要です。慣れるまでは逆に入力が遅くなっていたように思います。
テキスト入力だけではなく、特にターミナルなどのコンソール入力時に非常に重宝しています。

List

Key Action
Ctrl + h Back space
Ctrl + d Delete
Ctrl + k Delete back words on now line
Ctrl + f Move to front
Ctrl + b Move to back
Ctrl + a Move to line top
Ctrl + e Move to line end
Ctrl + c Cancel now line
Ctrl + p Select previous history command
Ctrl + n Show next command
Ctrl + l Clear window

Impression

  • Ctrl + h
    • 一番重宝しています。deleteキーをタイプせずにすむようになったため、手の移動のストレスがかなり減りました。
  • Ctrl + c
    • コンソール入力時によく使います。コマンドの入力を削除せずにキャンセルしたい時に使用します。
  • Ctrl + p & Ctrl + n
    • コンソール入力時に重宝しています。矢印キーを使用せずにすみます。過去のコマンドを実行したい時に使用します。
  • Ctrl + l
    • コンソール入力時に重宝しています。画面の表示をクリアにしたい時に使用します。

色々な操作を覚えることでホームポジションから移動する手間が減りましたが、全ての操作がカバーできているわけではありません。テキスト入力をしていると、行を移動したい場合などがあり、その辺りがまだカバーできていないため、方法が無いか調べる必要があると感じています。
また、自分はエディタとしてvimを使用していますが、操作系が異なるためたまに混乱することがあります。この辺りも上手く解決する必要がないか調べる必要があると感じています。