Помилка "Вікна програм мають мати контролер кореневого перегляду в кінці запуску програми" під час запуску проекту з Xcode 7, iOS 9


89

Після запуску функції

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

відбувається збій:

 Assertion failure in 
-[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', `enter code here`reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000109377885 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000108df0df1 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001093776ea +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x0000000108a42bb1 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
    4   UIKit                               0x000000010760e350 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2875
    5   UIKit                               0x000000010760b73f -[UIApplication workspaceDidEndTransaction:] + 188
    6   FrontBoardServices                  0x000000010b87fd7b FrontBoardServices + 163195
    7   FrontBoardServices                  0x000000010b880118 FrontBoardServices + 164120
    8   CoreFoundation                      0x00000001092a20f1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    9   CoreFoundation                      0x0000000109297eac __CFRunLoopDoSources0 + 556
    10  CoreFoundation                      0x0000000109297363 __CFRunLoopRun + 867
    11  CoreFoundation                      0x0000000109296d78 CFRunLoopRunSpecific + 488
    12  UIKit                               0x000000010760b091 -[UIApplication _run] + 402
    13  UIKit                               0x000000010760f79b UIApplicationMain + 171
    14  bbwc                                0x00000001037a9998 main + 344
    15  libdyld.dylib                       0x000000010a45ca05 libdyld.dylib + 10757
    16  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Цей проект є старим проектом, що мені робити, щоб його будувати та запускати з Xcode 7 та iOS 9?


Оскільки Xcode 7 є бета-версією, вам слід, мабуть, повернутися до Xcode 6 для будь-якої серйозної роботи з розробки.
Paul R,


привіт, я отримую цей ероор: - *** Помилка твердження у - [UIApplication _runWithMainScene: переходКонтекст: завершення:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 як це вирішити
Akash Raghani

Відповіді:


175

З вашого повідомлення про помилку:

Очікується, що вікна програм матимуть контролер кореневого перегляду в кінці запуску програми

Скільки років цьому "старому" проекту? Якщо це більше кількох років, у вас все ще є:

[window addSubview:viewController.view];

Натомість вам слід замінити його на:

[window setRootViewController:viewController];

1
У мене така сама проблема, і я думаю, що це проблема iOS 9. Мій проект працює в iOS 7 і 8. Чомусь подання з розкадровки встановлено неправильно.
Девід Снабель-Коунт,

3
Дуже дякую . відповідь у повідомленні про помилку: "Вікна програми" Я виявляю, що у моєму проекті є два вікна, одне - звичайна вдова, інша - сторонній модуль, який називається
andrew wang

3
MTStatusBarOverlay і він не має RootViewController, iOS9 вимагає, щоб усе вікно мало мати rootViewController.
Andrew Wang

1
Так, врешті-решт я знайшов те саме питання. У мого додатка є додаткове вікно, в якому немає контролера кореневого перегляду.
Девід Снабель-Коунт,

1
Я знайшов рішення , який працює для мене: stackoverflow.com/a/32719949/1881895
barrast

37

Якщо ви вже встановили rootViewController вашого self.window в делегатові програми і все ще отримуєте цю помилку під час виконання, то у вашому додатку UIA, ймовірно, є більше одного вікна, одне з яких може не мати пов’язаного rootViewController. Ви можете прокрутити вікна додатків і пов’язати порожній viewController з його rootViewController, щоб виправити отриману помилку.

Ось код, який циклічно переглядає вікна програми та пов'язує порожній ViewController з rootViewController, якщо у вікні його немає.

NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows) {
    NSLog(@"window: %@",window.description);
    if(window.rootViewController == nil){
        UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
        window.rootViewController = vc;
    }
}

Оновлення: очевидно, є вікно, присвячене рядку стану, яке зазвичай спричиняє цю проблему. Наведений вище код повинен виправити цю помилку.


2
Дякую!! Це виявилось для мене проблемою. Я встановив головний контролер перегляду, але у програми було друге вікно, про яке я не знав.
n13

Настільки твердий ... Я не новачок, і цей мене отримав під час оновлення до Xcode 7.1 під управлінням iOS 9.1 ... У рядку стану є вікно, виділене ... звичайно, що ?! Я приховую рядок стану, якщо це для когось щось означає.
whyoz

Нічого собі, у мене 2 з 12 моїх програм аварійно розглядались, і це, здається, це виправляє.
Ендрю Сміт

Працювали чудово !! Потрібно любити "Очевидно, є вікно, присвячене рядку стану, яке зазвичай спричиняє цю проблему." НЕ бачив, що це з'являється.
eGanges

1
Цей метод може призвести до того, що viewDidLoad і viewWillAppear будуть викликані двічі на вашому rootViewController. Якщо у вас є вікно ініціювання вручну, перевірте свій plist і переконайтеся, що у вас НЕ вказано Window.xib як "Основне ім'я основного файлу nib", якщо після використання цього обхідного способу ви бачите двічі, що викликаються. Тоді вам просто потрібно видалити цей код і setRootViewController, як це робиться зазвичай.
whyoz

21

XCODE 7 вимагає, щоб усі Windows мали мати rootViewController. Ви можете легко використовувати:

UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
self.window.rootViewController = vc;

Це добре працює, якщо вам потрібно використовувати лише UIWindow (для простих прикладів з будь-яких підручників - до Xcode 7)!


Ласкаво просимо до Stack Overflow! Будь ласка, подумайте про редагування вашого допису, щоб додати більше пояснень щодо того, що робить ваш код, і чому це вирішить проблему. Відповідь, яка здебільшого містить лише код (навіть якщо він працює), як правило, не допомагає ОП зрозуміти свою проблему.
SuperBiased,

Дякуємо, що уникнуло попередження мого iOS ~ 3–8 => аварії iOS 9, але дало попередження статичного аналізатора про витік. Тож я перемістив оголошення до інтерфейсу в заголовку із призначенням у applicationDidFinishLaunching. Потім я додав [vc release] до dealloc.
Flash Sheridan

13

Здається, що з iOS 9.1 (?) Або Xcode 7.1 будь-який UIWindowекземпляр application(_:didFinishLaunchingWithOptions:), створений під час, повинен матиrootViewController створений набір, перш ніж залишати цей метод.

Раніше було достатньо, щоб лише головне вікно мало rootViewControllerнабір під час цього методу. Тепер будь-який UIWindowекземпляр повинен мати дійснийrootViewController властивість.

Винуватцем тут може бути ваш власний код, якщо ви користуєтесь, UIWindowа також будь-яка інша стороння бібліотека, яка намагається ініціалізувати новий UIWindowекземпляр протягом цього часу (наприклад, накладання повідомлень у рядку стану тощо).

ПРИМІТКА . Ви також отримуєте ту саму помилку, якщо не встановили параметр rootViewControlerу головному вікні або якщо ваша розкадровка налаштована неправильно. Згадуючи це як побічну ноту, оскільки ці випадки досить очевидні та прості для виправлення.


Ви чудові: D, дякую, я просто коментую ініціалізацію вікна, і зараз все гаразд
Мохаммад Алабід

3

Це мене вкусило і сьогодні, і це виправило мені кілька годин: у мого додатка є вікно у "MainWindow.xib", в комплекті з контролером навігації та супровідним контролером кореневого перегляду, які всі автоматично створювались у належному порядку , з Xcode 6 та iOS8.

У iOS9 ця програма все ще працює нормально при завантаженні з AppStore, але не при нещодавній побудові за допомогою Xcode 7 і запуску на iOS 9. На той час, коли делегат програми виконує свій applicationDidBecomeActive: метод, контролер кореневого перегляду тепер не працює завантажений, оскільки він раніше було раніше! Це змусило кореневий контролер подання пропустити виклик мого коду стану відновлення.

Я виправив це, створивши сам екземпляр контролера кореневого перегляду в коді та відреставрувавши його стан із viewDidLoad, явно.


2

Ви повинні встановити властивість rootviewcontroller кожного вікна у вашому додатку


Ваша відповідь мені допомогла
Aznix

2

У мене є старий проект, який працював в iOS 8, але не в iOS 9. Якщо для вашого основного інтерфейсу встановлено значення MainWindow.xib, оновіть його до розкадрування. Це мені це виправило:

  1. Створіть новий проект, програма Single View - це нормально.
  2. Скопіюйте файл Main.storyboard до свого проекту, або ви можете просто створити власний.
  3. Відкрийте налаштування проекту та встановіть для основного інтерфейсу значення Main.storyboard Встановіть для основного інтерфейсу значення Main.storyboard

1

Просто встановіть свій rootViewController на NaviController, який є вашим UIViewController в app-delegate.rb, як мій код нижче. Я новачок у рубіні, але сподіваюся, це допомогло ...

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController

1

Я вирішив цю проблему з додатком, який мені більше або менше передається у спадок. Перевіривши, що розкадровка була належним чином налаштована як основний інтерфейс програм, і що в розкадруванні був RootViewController, я все ще отримував збій.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'

Що я виявив після подальшого розслідування, що збій був спричинений якоюсь логікою перегляду (SVProgressHud) - (void)applicationDidBecomeActive:(UIApplication *)application. Здається, це нова поведінка в Xcode7, але, наскільки я можу сказати, SVProgressHud посилався на контролер rootview до того, як його було встановлено на розкадруванні. Врешті-решт оновлення SVProgressHud до 2.0 виправило помилку.


0

Рішення Swift 2, яке мені підходило:

Вставте код нижче в AppDelegate -> didFinishLaunchingWithOptions

self.window!.rootViewController = storyboard.instantiateViewControllerWithIdentifier("YourRootViewController") as? YourRootViewControllerClass

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.