Universal iOS app crashing on iPhone/iTouch 3.1.3 due to UIPopoverController

喜欢而已 提交于 2020-01-15 05:51:08

问题


I just updated my app so that it's a universal app. In doing so I added support for UIPopoverController in a certain place. Now the app seems to be crashing on 3.1.3 iPhone/iTouch devices:

OS Version:      iPhone OS 3.1.3 (7E18)
Report Version:  104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x00000001, 0xe7ffdefe
Crashed Thread:  0

Dyld Error Message:
  Symbol not found: _OBJC_CLASS_$_UIPopoverController

What I don't get is that I'm only trying to call UIPopoverController if the hardware is an iPad:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:btc];
    CGSize popoverSize = { 300.0, 500.0 };
    popover.delegate = self;
    popover.popoverContentSize = popoverSize;
    self.bmPopover = popover;
    [popover release];

    [self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
    [self presentModalViewController:nav animated:YES];
}

I do have an iVar and a property of type UIPopoverController declared but I wouldn't have expected this to cause an issue at runtime if I didn't actually try to call methods in the class.

What am I supposed to do to make sure that the system doesn't try to link with UIPopoverController at runtime when this isn't supported?


回答1:


For Universal app you should not only check if this is ipad or does this class exists but you should link UIKit as Weak reference a not default ( strong ), to do this:

  1. get to target info
  2. select general
  3. in linked libraries change UIKit required to UIKit weak

Have fun making universal apps :]




回答2:


Even though this code would most likely never run on the iPhone, it will still be linked and thus you are receiving the error. Before instantiating, you need to check if the class exists. You can modify your code above to the following which will fix it.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    Class UIPopoverControllerClass = NSClassFromString(@"UIPopoverController");
    if (UIPopoverControllerClass != nil) {
        UIPopoverController *popover = [[UIPopoverControllerClass alloc] initWithContentViewController:btc];
        CGSize popoverSize = { 300.0, 500.0 };
        popover.delegate = self;
        popover.popoverContentSize = popoverSize;
        self.bmPopover = popover;
        [popover release];

        [self.bmPopover presentPopoverFromBarButtonItem:self.bmBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
} else {
    [self presentModalViewController:nav animated:YES];
}

Also, you could weak link against the UIKit framework, which would also solve the problem. I prefer the code solution as it is more safe.




回答3:


You need to stop the compiler errors by referencing the class from a string. This should be used in tandem with UI_USER_INTERFACE_IDIOM() and will compile on an SDK that does not know about UIPopoverController. Here is an example:

Class popClass = NSClassFromString(@"UIPopoverController");
if(popClass) {
    id infoPop = [[popClass alloc] initWithContentViewController:popViewController];
    [infoPop presentPopoverFromRect:CGRectMake(20, 70, 10, 10) inView:self.view permittedArrowDirections:4 animated:YES];
}



回答4:


The easy answer:

In your Xcode project, Select the top level project icon. Do a Get Info, go to the BUILD panel. set Configurations to All Configurations, set Show: to ** All Settings**

Set the iOS Deployment Target to iOS 3.1.

Recompile. Your program is failing because the minimum OS is set too high, so the loader can't resolve the symbol UIPopoverController. The change I just walked you through makes that symbol weak: it will resolve to NULL, but at least your program will load.


Are you loading a NIB file that implicitly creates a UIPopoverController? That's another way to crash.




回答5:


I found it useful to add this, so that I could use UI_USER_INTERFACE_IDIOM() on pre-3.2 systems.

#ifndef __IPHONE_3_2    // if iPhoneOS is 3.2 or greater then __IPHONE_3_2 will be defined

typedef enum {
    UIUserInterfaceIdiomPhone,           // iPhone and iPod touch style UI
    UIUserInterfaceIdiomPad,             // iPad style UI
} UIUserInterfaceIdiom;

#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone

#endif // ifndef __IPHONE_3_2


来源:https://stackoverflow.com/questions/3983518/universal-ios-app-crashing-on-iphone-itouch-3-1-3-due-to-uipopovercontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!