XcodeのiPadシミュレーターで正常に動作するiPhoneおよびiPadユニバーサルアプリを作成しましたが、iPhoneの機能をテストしたいと思います。このコードでは常にデフォルトでiPadになっているため、iPhoneシミュレーターを実行できないようです。
代わりに、デバイスで実行しようとしましたが、実行を開始すると、次のエラーが発生します。
dyld: Symbol not found: _OBJC_CLASS_$_UISplitViewController
Referenced from: /var/mobile/Applications/9770ACFA-0B88-41D4-AF56-77B66B324640/Test.app/Test
Expected in: /System/Library/Frameworks/UIKit.framework/UIKit in /var/mobile/Applications/9770ACFA-0B88-41D4-AF56-77B66B324640/Test.app/TEST
アプリはXIBを使用するのではなくプログラムで構築されるため、main.mメソッドで次の行を使用して2つのデバイスロジックを分割しました。
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Pad");
}
else
{
retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Phone");
}
その時点から、それらは異なるAppDelegatesを使用し、ヘッダーをチェックして、UISplitViewが使用されたり、Phoneロジックを介してインポートされたりしないことを確認しました。
このエラーを回避するにはどうすればよいですか。また、プログラムで作成されたこのアプリでユニバーサルロジックパスを分割するためのより良い方法はありますか?
UIKitフレームワークを弱くリンクしなかったため、このエラーがトリガーされています。 iPhone OS 3.2のUIKitフレームワークはUISplitViewControllerを追加しました。通常どおりリンクすると、アプリケーションはそれらのシンボルが3.0に存在すると想定しますが、存在しないと見なします。
フレームワークをウィークリンクするには、Xcodeでアプリケーションターゲットを見つけて検査し、[全般]タブに移動します。そのタブの下部には、タイプの列を含むフレームワークのリストがあります。 UIKitのタイプを必須から弱くに変更し、アプリケーションを再構築します。これでランタイムエラーが処理されます。
あなたの条件付きロジックは健全ですが、私はアプリケーションデリゲートを共有し、インターフェイス固有のレイアウトをさらに先に行う傾向があります。
(更新:2011年12月21日)iOS 4.2以降、このようなエラーを防ぐためにフレームワークを弱くする必要はなくなりました。 Marco Armentの説明 のように、iOS 4.2以降でビルドし、iPhone OS 3.1以降をターゲットにしている場合、個々のクラスは弱くリンクされているため、+class
メソッドは、現在実行中のバージョンのOSにクラスが存在しない場合、nil
を返します。
私は非常によく似たエラーを抱えていました、そしてそれは私を狂わせていました! :-)何時間も検索していて、理解できませんでした...
あなたが言ったように、iPad Simulatorで実行しているときはすべて問題ありませんでしたが、iPhone OS 3.1.2を搭載したiPhoneでアプリをテストしようとすると、起動せずに次のエラーメッセージが表示されてクラッシュしました。
mi_cmd_stack_list_framesスタックに十分なフレームがありません
コードのほぼすべての行をチェックすることで、UIPopoverControllerやUISplitViewController(すでにフォークされたiPad固有のコード内)などの3.2クラスの割り当てが問題の原因であることがわかりました。
つまり、代わりに:
infoPopover = [[UIPopoverController alloc] initWithContentViewController:infoNavController];
私は書くだろう
infoPopover = [[NSClassFromString(@ "UIPopoverController")alloc] initWithContentViewController:infoNavController];
そしてそれは私の問題を解決しました! (エラーメッセージでバグがどこにあるのかわからない場合、デバッグは非常に困難になる可能性があります...)
私を助けたのは: