简体   繁体   中英

Separate Storyboards for iPhone 4 and iPhone 5 Cause Crash in Simulator Only

I have 2 storyboards setup in my project, one for iPhone 4 and one for iPhone 5.

I have setup the code to switch storyboards in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions as follows:

  CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;

    if (iOSDeviceScreenSize.height == 480)
    {
        // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
        UIStoryboard *Storyboard_iPhone4 = [UIStoryboard storyboardWithName:@"Storyboard_iPhone4" bundle:nil];

        // Instantiate the initial view controller object from the storyboard
        UIViewController *initialViewController = [Storyboard_iPhone4 instantiateInitialViewController];

        // Instantiate a UIWindow object and initialize it with the screen size of the iOS device
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

        // Set the initial view controller to be the root view controller of the window object
        self.window.rootViewController  = initialViewController;

        // Set the window object to be the key window and show it
        [self.window makeKeyAndVisible];
    }

    if (iOSDeviceScreenSize.height >= 568)
    {   // iPhone 5 and iPod Touch 5th generation: 4 inch screen
        // Instantiate a new storyboard object using the storyboard file named Main
        UIStoryboard *Main2 = [UIStoryboard storyboardWithName:@"Main2" bundle:nil];

        UIViewController *initialViewController = [Main2 instantiateInitialViewController];
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.window.rootViewController  = initialViewController;
        [self.window makeKeyAndVisible];
    }
    else
    {
        UIStoryboard *Main2 = [UIStoryboard storyboardWithName:@"Main2" bundle:nil];
        UIViewController *initialViewController = [Main2 instantiateInitialViewController];
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.window.rootViewController  = initialViewController;
        [self.window makeKeyAndVisible];
    }

I will receive the following error when running on simulator only (iPhone 4 and iPhone 5 devices work and switch storyboards as expected):

Thread 1: EXC_BAD_ACCESS (code=2, address=0xc)

This occurs here:

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

I am working in Xcode 5 currently.

Here is the trace (not sure if I did this correctly):

libobjc.A.dylib`objc_msgSend:
0x260e0a4:  movl   0x8(%esp), %ecx
0x260e0a8:  movl   0x4(%esp), %eax
0x260e0ac:  testl  %eax, %eax
0x260e0ae:  je     0x260e110                 ; objc_msgSend + 108
0x260e0b0:  movl   (%eax), %edx
0x260e0b2:  movzwl 0xc(%edx), %eax
0x260e0b6:  andl   %ecx, %eax
0x260e0b8:  shll   $0x3, %eax
0x260e0bb:  addl   0x8(%edx), %eax
0x260e0be:  cmpl   (%eax), %ecx
0x260e0c0:  jne    0x260e0c5                 ; objc_msgSend + 33
0x260e0c2:  jmpl   *0x4(%eax)
0x260e0c5:  cmpl   $0x0, (%eax)
0x260e0c8:  je     0x260e119                 ; objc_msgSend + 117
0x260e0ca:  cmpl   0x8(%edx), %eax
0x260e0cd:  je     0x260e0d9                 ; objc_msgSend + 53
0x260e0cf:  subl   $0x8, %eax
0x260e0d2:  cmpl   (%eax), %ecx
0x260e0d4:  jne    0x260e0c5                 ; objc_msgSend + 33
0x260e0d6:  jmpl   *0x4(%eax)
0x260e0d9:  movzwl 0xc(%edx), %eax
0x260e0dd:  shll   $0x3, %eax
0x260e0e0:  addl   0x8(%edx), %eax
0x260e0e3:  jmp    0x260e0f2                 ; objc_msgSend + 78
0x260e0e5:  cmpl   $0x0, (%eax)
0x260e0e8:  je     0x260e119                 ; objc_msgSend + 117
0x260e0ea:  cmpl   0x8(%edx), %eax
0x260e0ed:  je     0x260e0f9                 ; objc_msgSend + 85
0x260e0ef:  subl   $0x8, %eax
0x260e0f2:  cmpl   (%eax), %ecx
0x260e0f4:  jne    0x260e0e5                 ; objc_msgSend + 65
0x260e0f6:  jmpl   *0x4(%eax)
0x260e0f9:  pushl  %ebp
0x260e0fa:  movl   %esp, %ebp
0x260e0fc:  pushl  $0x0
0x260e0fe:  pushl  $0x0
0x260e100:  pushl  $0x0
0x260e102:  pushl  %edx
0x260e103:  pushl  %ecx
0x260e104:  movl   0x8(%ebp), %ecx
0x260e107:  pushl  %ecx
0x260e108:  calll  0x25fc720                 ; objc_msgSend_corrupt_cache_error
0x260e10d:  nopl   (%eax)
0x260e110:  xorl   %edx, %edx
0x260e112:  xorps  %xmm0, %xmm0
0x260e115:  xorps  %xmm1, %xmm1
0x260e118:  ret    
0x260e119:  movl   0x8(%esp), %ecx
0x260e11d:  movl   0x4(%esp), %eax
0x260e121:  pushl  %ebp
0x260e122:  movl   %esp, %ebp
0x260e124:  subl   $0xc, %esp
0x260e127:  pushl  %edx
0x260e128:  pushl  %ecx
0x260e129:  pushl  %eax
0x260e12a:  calll  0x260606f                 ; _class_lookupMethodAndLoadCache3
0x260e12f:  leave  
0x260e130:  cmpl   %eax, %eax
0x260e132:  jmpl   *%eax

So based on the image of the console the crash is because a message is sent to a deallloced instance. You can see from right about the lldb() it says [_UIDelayedPresentationContext delayingController] message sent to dealloced instance

I'm wondering what devices this crashes on in the simulator - does it crash on both 3.5 and 4 inch devices?

One thing that pops out to me is that your first if statement kicks off the process to create a UIWindow and a UINavigationController along with it from the Storyboard_iPhone4 storyboard. Then immediately after that you have an if-else which does exactly the same thing but from a different storyboard. So if the device is not a 4 inch device you end up creating the window twice and I'm wondering if somehow that's the source of the crash. If you remove the first if statement does that change things?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM