应用程序在UISplitViewController的viewWillAppear中崩溃

时间:2014-09-29 16:00:55

标签: ios objective-c ios8

我正在开发一个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 initviewDidLoad - 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:]。)。

1 个答案:

答案 0 :(得分:4)

默认preferredDisplayMode似乎是UISplitViewControllerDisplayModeAutomatic,并且UISplitViewController正在执行某些,当它具有该显示模式时会以纵向创建一个弹出控制器并调用{{ 1}}或旋转。

为避免崩溃,我添加了代码以更改viewWillAppear方法中的显示模式:

viewDidLoad