大文字小文字の違いで実行時エラー

MyController *newController = [[MyController alloc] initWithNibName:@"Mycontroller" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] newController];

こんな感じの良くあるコード。シミュレータだと問題なく動いてた。で、実機だと実行時にこんなエラー。

2011-02-18 14:20:38.245 MyTest[1176:307] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </var/mobile/Applications/xxxxxxxxx/MyTest.app> (loaded)' with name 'Mycontroller''

Xcode の Resources フォルダにちゃんと MyController.xib 入ってるし…。っていうか、ちゃんとシミュレータでは動いてるから見つからないなんておかしいじゃん!
と、あれこれ悩んでたら @"Mycontroller" の "c" が小文字だった! シミュレータだと大文字と小文字を区別しないけど、実機だと区別をしてるってことか…。シミュレータは起動しているマシンの設定によるのかな? 自分の iMac は大文字と小文字の区別をしない設定だっけ。
というわけで、以下のように修正して問題は解決。

MyController *newController = [[MyController alloc] initWithNibName:@"MyController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] newController];

この件は以前にどこかで読んだことがある気がするけど…。自分がハマっている間はそれを思い出せないんだよな〜。

メインスレッドじゃないと聞いてくれない?

ALAssetsLibrary を使うと「位置情報にアクセスします」ってなダイアログを出してユーザに位置情報にアクセスして良いかどうかの確認をしてくれる。で、一度 OK に設定すればそれ以降は特に確認無しでアクセスができる。もちろん NG に変更することも<設定>アプリケーションの<位置情報サービス>で可能だ。

で、この確認のダイアログっていつ出るの?って話。
自分の場合こんな感じで困ってた。

  1. 最初にテストアプリを作って ALAssetsLibrary にアクセスするコードを書いた。もちろん、実機での最初の起動時に確認ダイアログが出て OK にしたので、それ以降も ALAssetsLibrary にアクセスして写真データにアクセスできてた。
  2. 次に実機だとそのアクセスとその後の処理に時間がかかるので、アクセスと処理の部分を別スレッドにした。これもちゃんと動いた。
  3. それじゃ、いよいよテストアプリでなく本番?アプリを書き始める。もちろん、最初から ALAssetsLibrary へのアクセスと処理は別スレッド。ガリガリ書いて確認はシミュレータで行って問題はない。
  4. とりあえず、それなりの形になったので実機で確認…。あれ? 画像の UIView が黒くてくるくる(ActivityIndicator)が回ったままだぞ…。画像が読み込めてない。シミュレータだと問題ないのに!
  5. で、コードを追ってみると実機では ALAssetsLibrary にアクセスできてない。また、良く考えてみると ALAssetsLibrary へアクセスする時の最初の確認ダイアログがこのアプリでは出てきたことがない。なので<設定>アプリの<位置情報サービス>にもこのアプリの名前は出てこない…。なんで???

というわけで、結果は ALAssetsLibrary にアクセスするコードが別スレッドの中にあったのがいけなかったみたい。これを別スレッドに分けないでみたら確認ダイアログも出てきて、問題なく ALAssetsLibrary にアクセスできるようになった。


シミュレータでは確認ダイアログが出てこないので常に ALAssetsLibrary へのアクセスは OK になっているのだと思う。だからシミュレータでは問題がなかった。でも、実機では<設定>アプリの<位置情報サービス>を OK にしないとアクセスできない。それなのに ALAssetsLibrary にアクセスするコードが別スレッドに入っていると、確認ダイアログが出てこないので<位置情報サービス>を OK にできずに ALAssetsLibrary にアクセスできない状態のままになってしまった。


と、思うのだけど、どうなのだろう?
とりあえずは、別スレッドで ALAssetsLibrary にアクセスするのを止めたので、この問題は解決できたわけだけど。