我正在开发一个iOS应用程序,它使用标签栏在UISplitViewController的子类的子类之间进行交换。直到iOS 8 GM种子(和发布版本),这工作正常。
然而,当使用适用于运行iOS 8的iPad的iOS 8 SDK构建时,在切换到一个(并且只有一个)视图控制器子类时,我不断遇到崩溃。这个崩溃会下降到超类(UISplitViewController)的viewWillAppear方法中,并且与在该方法中设置的Popover有关:
2014-09-29 09:24:13.526 AppName[51815:2369763] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with `nil`.'
*** First throw call stack:
(
0 CoreFoundation 0x0363adf6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x031fda97 objc_exception_throw + 44
2 CoreFoundation 0x0363ad1d +[NSException raise:format:] + 141
3 UIKit 0x012eaabe -[UIPopoverController _initWithContentViewController:popoverControllerStyle:] + 436
4 UIKit 0x0111eb43 -[UISplitViewController _setupHiddenPopoverControllerWithViewController:] + 122
5 UIKit 0x0111ed82 -[UISplitViewController _viewControllerHiding:] + 322
6 UIKit 0x0112556a -[UISplitViewController viewWillAppear:] + 189
7 AppName 0x001ac9c0 -[BaseSplitViewController viewWillAppear:] + 624
8 AppName 0x00342b82 -[HomeGlanceController viewWillAppear:] + 306
9 UIKit 0x00d7914f -[UIViewController _setViewAppearState:isAnimating:] + 545
10 UIKit 0x00d796ca -[UIViewController __viewWillAppear:] + 148
11 UIKit 0x00d910b1 -[UIViewController(UIContainerViewControllerProtectedMethods) beginAppearanceTransition:animated:] + 200
12 UIKit 0x00dc2dd3 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 619
13 UIKit 0x00dc2352 -[UITabBarController transitionFromViewController:toViewController:] + 64
14 UIKit 0x00dbe545 -[UITabBarController _setSelectedViewController:] + 340
15 UIKit 0x00dbe3c7 -[UITabBarController setSelectedViewController:] + 193
16 UIKit 0x00dc222b -[UITabBarController _tabBarItemClicked:] + 326
17 libobjc.A.dylib 0x032137cd -[NSObject performSelector:withObject:withObject:] + 84
18 UIKit 0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99
19 UIKit 0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
20 UIKit 0x00f6228d -[UITabBar _sendAction:withEvent:] + 466
21 libobjc.A.dylib 0x032137cd -[NSObject performSelector:withObject:withObject:] + 84
22 UIKit 0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99
23 UIKit 0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
24 UIKit 0x00d52a16 -[UIControl sendAction:to:forEvent:] + 69
25 UIKit 0x00d52e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
26 UIKit 0x00d52a4e -[UIControl sendActionsForControlEvents:] + 48
27 UIKit 0x00f670b1 -[UITabBar(Static) _buttonUp:] + 123
28 libobjc.A.dylib 0x032137cd -[NSObject performSelector:withObject:withObject:] + 84
29 UIKit 0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99
30 UIKit 0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
31 UIKit 0x00d52a16 -[UIControl sendAction:to:forEvent:] + 69
32 UIKit 0x00d52e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
33 UIKit 0x00d5209d -[UIControl touchesEnded:withEvent:] + 660
34 UIKit 0x00c6faba -[UIWindow _sendTouchesForEvent:] + 874
35 UIKit 0x00c70595 -[UIWindow sendEvent:] + 791
36 AppName 0x004527b4 -[LHCWindow sendEvent:] + 100
37 UIKit 0x00c35aa9 -[UIApplication sendEvent:] + 242
38 UIKit 0x00c458de _UIApplicationHandleEventFromQueueEvent + 20690
39 UIKit 0x00c1a079 _UIApplicationHandleEventQueue + 2206
40 CoreFoundation 0x0355e7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
41 CoreFoundation 0x035542cd __CFRunLoopDoSources0 + 253
42 CoreFoundation 0x03553828 __CFRunLoopRun + 952
43 CoreFoundation 0x035531ab CFRunLoopRunSpecific + 443
44 CoreFoundation 0x03552fdb CFRunLoopRunInMode + 123
45 GraphicsServices 0x0567524f GSEventRunModal + 192
46 GraphicsServices 0x0567508c GSEventRun + 104
47 UIKit 0x00c1de16 UIApplicationMain + 1526
48 AppName 0x0004c3de main + 222
49 libdyld.dylib 0x03b09ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
我发现有问题的ViewController在第一次显示时有三个子视图,但是当我删除共享一个帧的两个子视图时(通过删除self.view addSubview
调用),崩溃仍然存在:< / p>
UIImageView, {{50, 10}, {260, 490}}
UIView, {{50, 10}, {260, 490}}
UIView, {{50, 510}, {670, 390}}
什么会导致UISplitViewController的子类中与popover相关的崩溃?
这是viewWillAppear:
中的BaseSplitViewController
。在[super viewWillAppear:animated]
行停止运行异常断点。
- (void)viewWillAppear:(BOOL)animated {
iPadAppDelegate *appDelegate_iPad = [Utils getAppDelegateForDeviceType:DEVICE_TYPE_IPAD];
if(![appDelegate_iPad getIsTabInitialised]) {
return ;
}
DDLogVerbose(@"%@ appearing",[self class]);
// Which tab is opening? Log it!
NSString *screen = [kAnalyticsNavigationPrefix stringByAppendingString:NSStringFromClass([self class])];
[AnalyticsManager logEvent:screen];
// Ensure we don't cover anything with the status bar in iOS 7. It looks like
// the orientation code wasn't being called anymore?
[self adjustControllerForOrientation:[self interfaceOrientation]];
[super viewWillAppear:animated];
}
BaseSplitViewController init
和viewDidLoad
- awakeFromNib
未被覆盖。
- (id)init {
if (self = [super init]) {
[self setInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
DDLogVerbose(@"%@ loaded",[self class]);
isModalViewPresent = NO;
self.view.backgroundColor = [UIColor whiteColor];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}
HomeGlanceController
子类BaseSplitViewController
(它是UISplitViewController的子类)。它是BSVC唯一崩溃的子类。
- (id)init {
if (self = [super init]) {
bIsAnyKeypadPresent = FALSE;
//to create the favorite zone screen view
favoriteScreenBackGroundView = [[UIView alloc] initWithFrame:CGRectMake(280, 0, 720, 430)];
favoriteScreenbackGroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 5, 667,405)];
favoriteZoneScreenMainView = [[UIView alloc] initWithFrame:CGRectMake(20, 40 ,640,340)];
favoriteKeypadScreenMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 50 ,200,330)];
// Initialize the layout for the Favorite Controller.
[self initFavoriteLayoutCoordinates];
UITabBarItem * tabBarItem = [[UITabBarItem alloc]initWithTitle:HomeGlanceTabTitle
image:[Utils getImageNamed:HomeGlanceIcon]
tag:1];
tabBarItem.selectedImage = [Utils getImageNamed:HomeGlanceSelectedIcon];
self.tabBarItem = tabBarItem;
tabBarItem = nil;
// pick the co-ordinates of the favorite view from the layout array.
if ([favControlCoordinatesArray count]>layoutID) {
[self setControllerCoordinates:[favControlCoordinatesArray objectAtIndex:layoutID]];
}
}
return self;
}
- (void) viewDidLoad {
// I've tried commenting all but the super call out. The crash remains
[self createImageViewForFavorites];
// to create the View for favorite zone
[self createBackGroundViewForFavoriteZoneScreen];
[self createFavoriteZoneScreenToolbar];
[self createFavoriteZoneScreenMainView];
[self createFavoriteKeypadScreenToolbar];
[super viewDidLoad];
}
- (void)viewWillAppear : (BOOL) animated {
[super viewWillAppear:animated];
[self startTimer];
iPadAppDelegate *appDelegate_iPad = [Utils getAppDelegateForDeviceType:DEVICE_TYPE_IPAD];
if(![appDelegate_iPad getIsTabInitialised])
{
return;
}
[self createFavoriteZoneScreenMainView];
[self createFavoriteKeypadScreenMainView];
// Snipped methods that don't impact the UI directly (commented out in this build)
}
显然只有当iPad处于(或转为)纵向模式时才会发生崩溃:
super willRotateToInterfaceOrientation:duration:
上崩溃。super viewWillAppear:
最终原因似乎相同(不能使用nil
调用[UIPopoverController initWithContentViewController:]。)。
答案 0 :(得分:4)
默认preferredDisplayMode
似乎是UISplitViewControllerDisplayModeAutomatic
,并且UISplitViewController正在执行某些,当它具有该显示模式时会以纵向创建一个弹出控制器并调用{{ 1}}或旋转。
为避免崩溃,我添加了代码以更改viewWillAppear
方法中的显示模式:
viewDidLoad