2015-10-01 3 views
21

Xcode 7.0.1Debugging UIKit аварии [UINavigationController initWithRootViewController]

Update:

последняя вещь, которую я попытался было сломать создание UINavigationController таким образом:

self.viewController = [[ProjectsViewController alloc] initWithNibName:@"ProjectsViewController_iPhone" bundle:nil]; 
    self.navigationController = [[UINavigationController alloc] init]; 
    [self.navigationController setViewControllers:@[self.viewController]]; 
    self.window.rootViewController = self.navigationController; 
    [self.window makeKeyAndVisible]; 

Doing это крушение теперь находится на

[self.window makeKeyAndVisible]; 

, но след точно такой же.

Я также попытался это с ванильным ViewController путем изменения

[self.navigationController setViewControllers:@[[[UIViewController alloc] init]]]; 

Тот же результат ...

Оригинал сообщение:

У меня есть аварии, которые я изо всех сил, чтобы понимаем - вот следа lldb: Обратите внимание на индекс

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 2147483648 beyond bounds [0 .. 2]' 
*** First throw call stack: 
(
0 CoreFoundation      0x035eaa94 __exceptionPreprocess + 180 
1 libobjc.A.dylib      0x03084e02 objc_exception_throw + 50 
2 CoreFoundation      0x034f92ed -[__NSArrayM removeObjectAtIndex:] + 445 
3 UIKit        0x018c20b2 -[UIView(Hierarchy) bringSubviewToFront:] + 260 
4 UIKit        0x0193daeb -[UINavigationBar layoutSubviews] + 3692 
5 UIKit        0x018d716b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 813 
6 libobjc.A.dylib      0x03099059 -[NSObject performSelector:withObject:] + 70 
7 QuartzCore       0x0096e60c -[CALayer layoutSublayers] + 144 
8 QuartzCore       0x0096228e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 388 
9 QuartzCore       0x00970b2c -[CALayer(CALayerPrivate) layoutBelowIfNeeded] + 44 
10 UIKit        0x018c4dca -[UIView(Hierarchy) layoutBelowIfNeeded] + 1244 
11 UIKit        0x01a117cf __74-[UINavigationController _positionNavigationBarHidden:edge:initialOffset:]_block_invoke + 36 
12 UIKit        0x018caca6 +[UIView(Animation) performWithoutAnimation:] + 82 
13 UIKit        0x01a1178d -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] + 922 
14 UIKit        0x01a1194c -[UINavigationController _positionNavigationBarHidden:edge:] + 326 
15 UIKit        0x01a12d5f -[UINavigationController _positionNavigationBarHidden:] + 49 
16 UIKit        0x01a1104a -[UINavigationController setNavigationBar:] + 1224 
17 UIKit        0x01a10a38 -[UINavigationController _navigationBarHiddenByDefault:] + 156 
18 UIKit        0x01a10997 -[UINavigationController navigationBar] + 41 
19 UIKit        0x01a17805 -[UINavigationController loadView] + 230 
20 UIKit        0x019d3338 -[UIViewController loadViewIfRequired] + 138 
21 UIKit        0x019d3cf1 -[UIViewController view] + 35 
22 UIKit        0x01a22226 -[UINavigationController pushViewController:transition:forceImmediate:] + 615 
23 UIKit        0x01a21e27 __54-[UINavigationController pushViewController:animated:]_block_invoke + 351 
24 UIKit        0x01a21c83 -[UINavigationController pushViewController:animated:] + 786 
25 UIKit        0x01a07be2 -[UINavigationController initWithRootViewController:] + 140 
26 DELETIA        0x0012954e -[AppDelegate application:didFinishLaunchingWithOptions:] + 1214 

Это зрелое приложение, которое уже некоторое время строилось и работало, но в текущем XCode это происходит.

Как вы можете видеть, что есть вызов UINavigationController: initWithRootViewController - вот код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
// deletia - non UIKit code 

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.tintColor = [UIColor darkGrayColor]; 

    self.viewController = [[ProjectsViewController alloc] initWithNibName:@"ProjectsViewController_iPhone" bundle:nil]; 

    self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 

// deletia - but the app crashes on the above line 
} 

Я попробовал несколько вещей, после того, глядя на некоторые подобные вопросы и ответы здесь на SO.

  • Я слышал, что это может произойти, если View на базе контроллера в строке состояния внешний вид установлен в YES в Info.plist - так я установил, что NO/ ДА

  • Я слышал, что некоторые утилиты UIGestureRecognizers могут вызывать проблемы. Поэтому я изучил XIB и гарантировал, что никаких действий с этим контроллером просмотра не происходит.

  • Я слышал, что если контроллер зрения корня не полностью инициализирован это может быть проблематично - поэтому я отложил призыв к UINavigationController на 1 секунду

  • Я неправильно доверенный ProjectsViewController - поэтому я Подставив его для ванильный UIViewController таким образом:

    self.navigationController = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] init]]; 
    

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

+0

Я заметил, что 2147483648 - 0x80000000, но не понимаю. У вас есть что-нибудь добавленное в UINavigationBar, которое система пытается удалить? возможно, попробуйте добавить кнопку в панель навигации и посмотреть, не меняется ли что-либо? – ishahak

+0

@ishahak Вы имеете в виду в xib? – Damo

+0

Да, потому что столбец сбоя показывает, что UINavigationBar запускал обработчик «layoutSubviews» -> bringSubviewToFront -> removeObjectAtIndex. Не знаю, почему он хочет удалить что-то из массива, но я бы попытался заполнить этот массив (subviews навигационной панели) большим количеством элементов. Я бы лично попытался воссоздать XIB, если не слишком сложно. – ishahak

ответ

6

Я думаю, что вы фокусируетесь на неправильной части кода.Как вы уже упоминали, он выходит из строя на линии [self.window makeKeyAndVisible], однако, вероятно, причиной аварии является тот факт, что эта строка вызывает загрузку и представление пользователю ProjectsViewController и UINavigationController. Глядя на журнал аварии вы в курсе, это часть, которую вы должны быть исследования:

2 CoreFoundation      0x034f92ed -[__NSArrayM removeObjectAtIndex:] + 445 
3 UIKit        0x018c20b2 -[UIView(Hierarchy) bringSubviewToFront:] + 260 
4 UIKit        0x0193daeb -[UINavigationBar layoutSubviews] + 3692 

Здесь можно увидеть, что IOS пытается макет подвидов в UINavigationBar, а затем удалить объект с индексом, который, вероятно, NSNotFound (что приведет к NSIntegerMax, что соответствует индексу, указанному в вашем журнале сбоев).

Для проведения дальнейших исследований аварии, я рекомендовал бы, выполнив следующие действия:

  1. Заменить ProjectsViewController экземпляр с UIViewController экземпляра без пользовательского файла .xib. (Я прочитал в своем оригинальном посте, что вы уже пробовали это, но все же я бы рекомендовал сделать это в качестве первого шага, чтобы устранить дополнительные проблемы, если их больше, чем на пути полного разрешения аварии). Важно убедиться, что вы не используете ваш .xib-файл на этом этапе, поскольку это может быть причиной сбоя (если есть какие-либо неправильно соединенные выходы или подобные проблемы).
  2. Есть ли в вашей навигационной панели какие-либо предметы? Опять же, я заметил, что вы упомянули в комментариях, что это не так, но я бы дважды проверял, возможно ли, что есть раздел кода, в котором элементы добавляются в панель при определенных условиях и удаляются, если они не выполняются. Это может привести к сбою, если элементы будут удалены из недопустимого индекса.
  3. Попробуйте найти места в вашем коде, которые специально звонят removeObjectAtIndex или любой другой NSMutableArray связанный вызов, который может быть вызван во время загрузки и отображения вашего исходного контроллера представления. Добавьте точку останова в эти места, чтобы увидеть, достигнуты ли они во время начальной загрузки. Если да, попробуйте добавить туда тест, чтобы убедиться, что индекс, который вы пытаетесь удалить объект, больше или равен нулю и меньше размера массива. Таким образом, если индекс, который вы пытаетесь получить, равен NSNotFound, он по крайней мере не приведет к сбою приложения (хорошая практика, независимо от текущей аварии). Если это решит проблему, вы можете продолжить исследование проблемы и попытаться понять, почему NSNotFound фактически получен как индекс и исправить проблему логически.

Надеюсь, что один из этих шагов поможет определить и устранить проблему. Удачи!

+1

Я согласен с тем, что навигационная панель должна быть моей первой точкой атаки, но, к сожалению, я не вижу никакого способа, которым я пытаюсь ее изменить/добавить/удалить или вообще что-то сделать с навигационной панелью вообще. – Damo

+0

Welp, щедрость и, похоже, новых ответов нет. Угадайте, что это получает! –

1

UINavigationController - это стек, в котором вы можете только нажать и поп UIViewController. Вы должны передать UIViewController на начальном навигационном контроллере. Но если вы не знаете RootViewController, тогда вы можете сделать это.

self.viewController = [[ProjectsViewController alloc] initWithNibName:@"ProjectsViewController_iPhone" bundle:nil]; 
    self.navigationController = [[UINavigationController alloc] init]; 
    [self.navigationController pushViewController:self.viewController animated:NO]; 
    self.window.rootViewController = self.navigationController; 
    [self.window makeKeyAndVisible]; 
+0

Как это может привести к аварии? –

Смежные вопросы