在Xcode 3.x和iOS 4下,如果在模拟器中发出未处理的异常信号,则在控制台输出中会产生异常堆栈跟踪(类似于Java).
当我在Xcode 4.2下的iOS 5中引发未处理的异常时,运行完全相同的应用程序代码,不会发生堆栈跟踪.(我确实弄清楚如何设置异常断点,但这不会在控制台中产生回溯.)
这仅仅是我需要在某处创建的Xcode设置,还是Xcode 4/iOS 5的"功能"?有没有办法恢复这一点功能?
不幸的是,添加一个uncaughtExceptionHandler不起作用.这是处理程序:
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"uncaughtExceptionHnadler -- Exception %@", [exception description]);
// Because iOS 5 doesn't provide a traceback, provide one here
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
// Let Flurry look at the error
[FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}
Run Code Online (Sandbox Code Playgroud)
(事实证明它已经存在,做Flurry的事情,所以我只是添加了堆栈跟踪.)
这是它启用的地方(只在声明处理程序的下面几行):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Enable uncaught exception handler to dump stack and let Flurry log the exception
NSUncaughtExceptionHandler* hdlr = NSGetUncaughtExceptionHandler();
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
NSUncaughtExceptionHandler* newHdlr = NSGetUncaughtExceptionHandler();
// TODO: Test
NSException* ex = [NSException exceptionWithName:@"AssertionFailure" reason:@"Test" userInfo:nil];
@throw ex;
Run Code Online (Sandbox Code Playgroud)
我设置断点使我能够检查两个检索到的处理程序值.第一个是nil,第二个是明显有效的地址.但是当抛出测试异常时,处理程序(在iOS 5模拟器中)永远不会得到控制.(虽然当我在iOS 4.2模拟器上运行时,它确实可以控制.)
NSExceptionHandlingMask在iPhone上显然无法进行设置.先决ExceptionHandling.framework条件不可用.
这有效:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
Run Code Online (Sandbox Code Playgroud)
Hot*_*cks 36
这有效:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
Run Code Online (Sandbox Code Playgroud)
对于ARC:
int main(int argc, char *argv[]) {
int retVal = -1;
@autoreleasepool {
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
}
return retVal;
}
Run Code Online (Sandbox Code Playgroud)
仍然在等待某种解释为什么默认转储不再起作用和/或为什么(甚至更严重)uncaughtExceptionHandler不起作用.但是,显然这个问题只影响模拟器.
有人指出,如果你转到Product - > Scheme - > Edit Scheme,选择"Run(Debug)",选择"Diagnostics"选项卡,然后单击"Log Exceptions",这将恢复缺少的Xcode默认异常记录,可能(我还没有尝试过)消除上述黑客的需要.
| 归档时间: |
|
| 查看次数: |
18982 次 |
| 最近记录: |