web-dev-qa-db-fra.com

Erreur de compilation de débogage de l'application universelle pour iPhone/iPad lors des tests sur iPhone

J'ai écrit une application universelle pour iPhone et iPad qui fonctionne bien dans le simulateur iPad sur Xcode, mais j'aimerais maintenant tester la fonctionnalité de l'iPhone. Il me semble impossible d'exécuter le simulateur iPhone avec ce code, car il utilise toujours l'iPad par défaut?

Au lieu de cela, j'ai essayé de fonctionner sur le périphérique et, dès qu'il commence à fonctionner, j'obtiens le message d'erreur suivant:

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

Comme l'application est créée par programme plutôt que d'utiliser XIB, j'ai divisé les deux logiques de périphérique à l'aide des lignes suivantes dans la méthode main.m:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Pad");
}
else
{
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate_Phone");
}

À partir de ce moment, ils utilisent différents AppDelegates et j'ai vérifié mes en-têtes pour m'assurer que UISplitView n'est jamais utilisé ni importé via la logique téléphonique.

Comment puis-je éviter cette erreur et existe-t-il un meilleur moyen de fractionner les chemins logiques universels dans cette application créée par programme?

30
andybee

Cette erreur est en train de se déclencher parce que vous n'avez pas lié de manière faible le framework UIKit. Le framework UIKit dans iPhone OS 3.2 a ajouté UISplitViewController. Si vous le liez normalement, votre application supposera que ces symboles existent sur la version 3.0, contrairement à ce qu'ils sont.

Pour lier faiblement un framework, recherchez la cible de votre application dans Xcode, inspectez-la et accédez à l'onglet Général. Au bas de cet onglet devrait figurer une liste de cadres, avec une colonne pour le type. Changez le type pour UIKit de Required à Required et régénérez votre application. Cela devrait régler les erreurs d’exécution.

Votre logique conditionnelle est valable, mais j'ai tendance à partager un délégué d'application et à effectuer la mise en page spécifique à l'interface plus loin.

(Mise à jour: 12/21/2011) À partir d'iOS 4.2, vous ne devriez plus avoir besoin de créer des liens faibles pour éviter de telles erreurs. Comme Marco Arment décrit , si vous construisez avec iOS 4.2 ou version ultérieure et ciblez jusqu'à iPhone OS 3.1 +, les classes individuelles sont désormais faiblement liées et doivent avoir leur méthode +class return nil si la classe n'existe pas sur la classe en cours d'exécution. version de l'OS.

66
Brad Larson

J'avais une erreur très similaire et ça me rendait dingue! :-) Chercher des heures et ne pas comprendre ...

Comme vous l'avez dit, tout fonctionnait correctement dans l'iPad Simulator, mais si vous tentiez de tester l'application sur l'iPhone avec iPhone OS 3.1.2, il ne démarrerait même pas mais se planterait avec le message d'erreur suivant:

mi_cmd_stack_list_frames pas assez de cadres dans la pile

En vérifiant presque toutes les lignes de code, je me suis rendu compte que l'allocation de classes 3.2 telles que UIPopoverController ou UISplitViewController (déjà dans du code spécifique à l'iPad fourchu) était à l'origine du problème.

Donc au lieu de i.e .:

infoPopover = [[UIPopoverController alloc]] initWithContentViewController: infoNavController];

je souhaiterai écrire

infoPopover = [[NSClassFromString (@ "UIPopoverController") alloc) initialWithContentViewController: infoNavController];

et cela a résolu mon problème! (Le débogage peut être si difficile si le message d'erreur ne vous donne aucune idée de l'endroit où le bogue pourrait éventuellement être trouvé ...)

4
xoconoxtle

Xcode 8.3, iPad 2 (uniquement), à partir de Swift 3

То помогло мне было:

  • перезапустите Xcode
  • сделать "Продукт -> Очистить"ShiftCommandK
  • перестроить проект
0
CousinCocaine