web-dev-qa-db-ja.com

iPhoneテスト用のユニバーサルiPhone / iPadアプリケーションデバッグコンパイルエラー

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ロジックを介してインポートされたりしないことを確認しました。

このエラーを回避するにはどうすればよいですか。また、プログラムで作成されたこのアプリでユニバーサルロジックパスを分割するためのより良い方法はありますか?

30
andybee

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を返します。

66
Brad Larson

私は非常によく似たエラーを抱えていました、そしてそれは私を狂わせていました! :-)何時間も検索していて、理解できませんでした...

あなたが言ったように、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];

そしてそれは私の問題を解決しました! (エラーメッセージでバグがどこにあるのかわからない場合、デバッグは非常に困難になる可能性があります...)

4
xoconoxtle

Xcode 8.3、iPad 2(網膜以外)、Swift 3 code

私を助けたのは:

  • xcodeを再起動します
  • 「製品->クリーン」を実行します ShiftCommandK
  • プロジェクトを再構築する
0
CousinCocaine