我刚刚更新了我的应用,因此它是一款通用应用。通过这样做,我在某个地方添加了对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
链接?
答案 0 :(得分:5)
对于通用应用程序,你不仅要检查这是否是ipad或者这个类是否存在,而且你应该将UIKit链接为弱引用而不是默认(强),为此:
制作通用应用程序的乐趣:]
答案 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