由于UIPopoverController,iPhone / iTouch 3.1.3上的通用iOS应用程序崩溃

时间:2010-10-21 00:58:32

标签: iphone cocoa-touch xcode ipad ios

我刚刚更新了我的应用,因此它是一款通用应用。通过这样做,我在某个地方添加了对UIPopoverController的支持。现在该应用程序似乎在3.1.3 iPhone / iTouch设备上崩溃:

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

我不知道的是,如果硬件是iPad,我只会尝试调用UIPopoverController:

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];
}

我确实声明了iVar和UIPopoverController类型的属性,但如果我实际上没有尝试在类中调用方法,我不会期望这会在运行时引起问题。

我不应该做什么来确保系统在运行时不会尝试与UIPopoverController链接?

5 个答案:

答案 0 :(得分:5)

对于通用应用程序,你不仅要检查这是否是ipad或者这个类是否存在,而且你应该将UIKit链接为弱引用而不是默认(强),为此:

  1. 获取目标信息
  2. 选择常规
  3. 链接库中的
  4. 更改了UIKit弱所需的UIKit
  5. 制作通用应用程序的乐趣:]

答案 1 :(得分:1)

尽管此代码很可能永远不会在iPhone上运行,但它仍然会被链接,因此您收到错误。在实例化之前,您需要检查该类是否存在。您可以将上面的代码修改为以下代码来修复它。

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];
}

此外,您可能会弱化与UIKit框架的链接,这也可以解决问题。我更喜欢代码解决方案,因为它更安全。

答案 2 :(得分:0)

您需要通过从字符串引用类来停止编译器错误。这应该与UI_USER_INTERFACE_IDIOM()一起使用,并将在不知道UIPopoverController的SDK上编译。这是一个例子:

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];
}

答案 3 :(得分:-1)

答案很简单:

在Xcode项目中,选择顶级项目图标。执行获取信息,转到构建面板。将配置设置为所有配置,将显示:设置为**所有设置**

iOS部署目标设置为iOS 3.1。

重新编译。您的程序失败,因为最小操作系统设置得太高,因此加载程序无法解析符号 UIPopoverController 。我刚刚走过的这个改变使得这个符号很弱:它将解析为NULL,但至少你的程序会加载。


您是否正在加载隐式创建UIPopoverController的NIB文件?这是另一种崩溃的方式。

答案 4 :(得分:-1)

我发现添加它很有用,这样我就可以在3.2之前的系统上使用UI_USER_INTERFACE_IDIOM()。

#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