«Ожидается, что окна приложений будут иметь корневой контроллер представления в конце запуска приложения», ошибка при запуске проекта с 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
привет, я получаю этот eroor: - *** Ошибка утверждения в - [UIApplication _runWithMainScene: transitionContext: Завершение:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 как это решить
Акаш Рагани

Ответы:

175

Из вашего сообщения об ошибке:

Ожидается, что окна приложений будут иметь корневой контроллер представления в конце запуска приложения.

Сколько лет этому «старому» проекту? Если прошло больше нескольких лет, остались ли у вас:

[window addSubview:viewController.view];

Вместо этого вы должны заменить его на:

[window setRootViewController:viewController];
Джеймс Вебстер
источник
1
У меня такая же проблема, и я думаю, что это проблема iOS 9. Мой проект работает в iOS 7 и 8. По какой-то причине вид из раскадровки настроен неправильно.
Дэвид Снабел-Коун
3
Большое спасибо . ответ находится в сообщении об ошибке: «Окна приложений» Я обнаружил, что в моем проекте есть два окна, одно - обычное окно, другое - сторонний модуль, вызываемый
Ван
3
MTStatusBarOverlay и у него нет RootViewController, iOS9 требует, чтобы все Window имели rootViewController.
Эндрю Ван
1
Да, в конце концов я обнаружил ту же проблему. В моем приложении есть дополнительное окно, в котором нет корневого контроллера представления.
Дэвид Снабел-Коунт
1
Я нашел решение, которое работает для меня: stackoverflow.com/a/32719949/1881895
barrast
37

Если вы уже установили rootViewController своего self.window в делегате приложения и по-прежнему получаете эту ошибку во время выполнения, то у вас, вероятно, есть более одного окна в вашем UIApplication, одно из которых может не иметь связанного 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;
    }
}

Обновление: по-видимому, есть окно, посвященное строке состояния, которое обычно вызывает эту проблему. Приведенный выше код должен исправить эту ошибку.

Bms270
источник
2
Благодарность!! Это оказалось для меня проблемой. Я установил главный контроллер представления, но в приложении было второе окно, о котором я не знал.
n13
Так твердо ... Я не новичок, и этот получил меня при обновлении до Xcode 7.1 под управлением iOS 9.1 ... В строке состояния есть выделенное окно ... конечно, есть ?! Я прячу строку состояния, если это для кого-то значит.
whyoz
Ничего себе, у меня 2 из 12 моих приложений вылетали при проверке приложений, и это, похоже, исправляет.
Эндрю Смит
Сработало отлично !! Должен любить "По-видимому, есть окно, посвященное строке состояния, которое обычно вызывает эту проблему." НЕ ожидал этого.
eGanges
1
Этот метод может привести к тому, что viewDidLoad и viewWillAppear будут вызываться дважды в вашем rootViewController. Если у вас есть окно инициализации вручную, проверьте свой список и убедитесь, что у вас НЕ определен Window.xib как «Основное имя файла пера», если вы видите, что вещи вызываются дважды после использования этого обходного пути. Затем вам просто нужно удалить этот код и установитьRootViewController, как обычно.
whyoz
21

XCODE 7 требует, чтобы вся ОС Windows имела rootViewController. Вы можете легко использовать:

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

Он работает хорошо, если вам нужно использовать только UIWindow (для простых примеров из любых учебников - до Xcode 7)!

Посланник
источник
Добро пожаловать в Stack Overflow! Пожалуйста, отредактируйте свой пост, чтобы добавить больше объяснений того, что делает ваш код и почему он решает проблему. Ответ, который в основном содержит просто код (даже если он работает), обычно не поможет OP понять их проблему.
SuperBiasedMan
Спасибо, это позволило избежать моего предупреждения iOS ~ 3–8 => сбой iOS 9, но выдало предупреждение статического анализатора об утечке. Поэтому я переместил объявление в интерфейс в заголовке с назначением в applicationDidFinishLaunching. Затем я добавил [vc release] в dealloc.
Флэш Шеридан,
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.

RickJansen
источник
2

Вы должны установить свойство rootviewcontroller каждого окна в своем приложении.

Алла
источник
Ваш ответ мне помог
Азникс 07
2

У меня есть более старый проект, который работал в iOS 8, но не в iOS 9. Если ваш основной интерфейс установлен на MainWindow.xib, обновите его до раскадровки. Это исправило это для меня:

  1. Создайте новый проект, приложение с одним представлением в порядке.
  2. Скопируйте файл Main.storyboard в свой проект или просто создайте свой собственный.
  3. Откройте настройки проекта и установите в качестве основного интерфейса Main.storyboard. Установите основной интерфейс на Main.storyboard
Адриан
источник
1

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

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController
BigPun86
источник
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 ссылался на rootviewcontroller до того, как он был установлен раскадровкой. В конечном итоге обновление SVProgressHud до 2.0 устранило ошибку.

Буэно
источник
0

Решение Swift 2, которое сработало для меня:

Вставьте приведенный ниже код в AppDelegate -> didFinishLaunchingWithOptions

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

Лиса5150
источник