技術日記
技術調査記録Edit

ASP.NET MVC 3で作成したアプリケーションをIISに手動で配置するにはどうすればいいんだ? Web発行ウィザードとかを使えば何とかなりそうなのはわかっているんだけど、そういうのを使わずに手動で配置できるようになっておかないと、何かトラブったときにどこをどう調べればいいのかわからなくなるから、まずは手動での配置の仕方を知っておきたい。

という調査をしようと思ったんだけど、ずっと放置していた件があるんでそっちを先に。iOS4の頃に作ったiPadアプリが、iOS5にしたら動かなくなった件。

MonoTouchを使うためにXcodeを3にしたり4にしたりいろいろいじったんで、開発環境の設定やライブラリ参照もだいぶ変わってしまっている可能性があるので、 ひとまずXcode4のiOS5対応最新版をダウンロード&インストール。テスト用のiPadをiOS5にアップデート。

プロファイルのアップデートとかいろいろやって、テスト機との接続環境を整えてから、プロジェクトをコンパイル&実行。と思ったらコンパイラの設定を変えろと言われる。 iOS 5 for Developers - Apple Developerに書いてある、

Automatic Reference Counting (ARC) for Objective-Cによって、メモリ管理をコンパイラの仕事にします。新しいApple LLVMコンパイラでARCを有効にすると、retainまたはreleaseを再度タイプする必要がなくなり、クラッシュやメモリリークを減らすと同時に、開発プロセスを飛躍的に簡素化します。コンパイラはオブジェクトを完全に理解し、もはや使われていない各オブジェクトを瞬時にリリースします。その結果,アプリケーションは、予測可能で滑らかな操作性を備えて、これまで以上に速く動作します。
のことか。従来方式で作っていたコードを、そのままApple LLVMコンパイラでコンパイルしてもいいのかな? ARCとやらは手動メモリ管理のコードもそのまま扱ってくれるのか?

さらに使っていたフォントArial Blackがなくなったとか言われる。でもなんかおかしいな。ios5 - Cannot apply some font as custom font on xcode 4.2 for develop iOS 5 application - Stack Overflowと同じ症状か。

Applications that want to use custom fonts can now include those fonts in their application bundle and register those fonts with the system by including the UIAppFonts key in their Info.plist file. The value of this key is an array of strings identifying the font files in the application’s bundle. When the system sees the key, it loads the specified fonts and makes them available to the application.
でも、これってiOS5になったからどうこうって話じゃないはずなんだけど。まあどうでもいい部分でしか使っていなかったから、ここは深追いしないでシステムフォントに変更することにする。 で、デバッグ実行してみたところ、

[sourcecode language="c"] warning: check_safe_call: could not restore current frame warning: Unable to restore previously selected frame. [/sourcecode]

とか出ている。

ググると、なんかプロジェクトをコピーしてコンパイルしなおせば直る、とかおまじない的な対処方法とか書かれていていやだなー。実際そういうこともたまにあるんだけどさ。

で、デバッグモードでコードを追っていったら、UIWebViewのsetScrollingEnabledを呼んでいるところでこけていた。これ非公式APIだったけど、iOS5では通らなくなったのか。しょうがないんで使うのをやめる。

それでひとまずは起動するようになったけど、今度UISwitchの表示がおかしくなったり、設定画面で終了ボタンを押しても元の画面に戻らなくなったり。

UISwitchの表示がおかしいのは、iOS5のUISwitchを日本語で使うと・・・:ゲームとかプログラムとかコーギーとか:So-netブログが原因だね。全部のxibファイルのLocalizationにJapaneseを追加。やってみるとわかるけど、XCode 4.2のその辺の操作性が軽くバグってる。実害はないけど。

終了ボタンで元の画面に戻らないのは、Dismiss modal view in iOS5 sdkが原因だった。モーダル表示したビューコントローラーから前の画面に戻るときに、従来は、

[sourcecode language="c++"] [self.parentViewController dismissModalViewControllerAnimated:NO]; [/sourcecode]

でいけたんだけど、iOS5からは、

[sourcecode language="c++"] [self.presentingViewController dismissModalViewControllerAnimated:NO]; [/sourcecode]

じゃなきゃだめになったようだ。

これでだいぶ動くようになったんだけど、まだ動かないコードがある。

モーダル表示されたビューコントローラから、呼び出し元のビューコントローラをself.parentViewControllerで解決しつつ、そのメソッドを呼ぶ処理を書いていたんだけど、どうやらself.parentViewControllerは呼び出し元のビューコントローラじゃなくなったらしく、そのメソッドが呼ばれてくれない。

これもさっきのモーダルビューを閉じるときのコードと同じく、parentViewControllerではなくpresentingViewControllerを使うと動く。これは結局公式にはどういう扱いなのかとヘルプドキュメントを読んでみたら、

Prior to iOS 5.0, if a view did not have a parent view controller and was being presented modally, the view controller that was presenting it would be returned. This is no longer the case. You can get the presenting view controller using the presentingViewController property.
iOS5以前ではモーダル表示されたビューがparentViewControllerを持たない場合は、parentViewControllerで呼び出し元のビューコントローラが取得できたけど、iOS5以降ではそうならないから、呼び出し元が欲しければpresentingViewControllerの方を使えって話なのね。

そう言われてみると、ビューの親子関係って本来はaddSubViewした場合に発生するから、モーダルビューと呼び出し元は親子関係じゃない。ただ、意味合い的には親子関係っぽいから、なんとなくparentViewControllerで呼び出せるようにしていた。でも、もうそれはやめて親ではなく、呼び出し元(presenting)として明示的に取得してね。ということなんだろう。確かに元々の仕様はあまり美しくないけど、今更こんなでかい仕様変更しなくてもいいのに。

しかも、この仕様変更はバージョン間の非互換性を自前のコードで埋めなければならないようで、OSバージョンとかpresentingViewControllerプロパティの有無とかを見ながら、どちらを使うか意識した実装が必要らしい。いっそUIViewControllerを自前で拡張して、modalParentViewControllerとかいうプロパティを追加するように書いた方がましかもな。Objective-Cで既存のクラスを外付けで拡張する書き方ってどんなんだっけ。

ひとまずiOS5にアップデートしたiPadではだいたい動くようになったけど、今度は以前は大量にコンテンツをロードした状態で動作させてもちゃんと動いていたのに、ある程度以上コンテンツをロードした状態で実行しようとするとアプリが落ちるようになっている。なんじゃこりゃ。

軽くデバッガーで追ってみたけど、UIWebViewとかUIImageViewとかにデータをロードしている途中で落ちたり落ちなかったりといった感じで、簡単には追求できなそうだったんで、いったん追求終了。

Published At2011-11-08 19:09Updated At2011-11-08 19:09