[IOS]程序异常crash捕获与拦截

来源:互联网 发布:人工智能发展现状论文 编辑:程序博客网 时间:2024/04/29 16:54
01.@interface UncaughtExceptionHandler : NSObject{ 02. BOOL dismissed; 03.} 04. 05.@end 06.void HandleException(NSException *exception); 07.void SignalHandler(int signal); 08. 09. 10.void InstallUncaughtExceptionHandler(void); 二:在.m文件编写 [plain] view plaincopy01.#import "UncaughtExceptionHandler.h" 02.#include 03.#include 04. 05.//http://www.cocoachina.com/newbie/tutorial/2012/0829/4672.html 06.NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName"; 07.NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey"; 08.NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey"; 09. 10.volatile int32_t UncaughtExceptionCount = 0; 11.const int32_t UncaughtExceptionMaximum = 10; 12. 13.const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4; 14.const NSInteger UncaughtExceptionHandlerReportAddressCount = 5; 15. 16.@implementation UncaughtExceptionHandler 17. 18.+ (NSArray *)backtrace 19.{ 20. void* callstack[128]; 21. int frames = backtrace(callstack, 128); 22. char **strs = backtrace_symbols(callstack, frames); 23. 24. int i; 25. NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames]; 26. for ( 27. i = UncaughtExceptionHandlerSkipAddressCount; 28. i < UncaughtExceptionHandlerSkipAddressCount + 29. UncaughtExceptionHandlerReportAddressCount; 30. i++) 31. { 32. [backtrace addObject:[NSString stringWithUTF8String:strs[i]]]; 33. } 34. free(strs); 35. 36. return backtrace; 37.} 38. 39.- (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex 40.{ 41. if (anIndex == 0) 42. { 43. dismissed = YES; 44. }else if (anIndex==1) { 45. NSLog(@"ssssssss"); 46. } 47.} 48. 49.- (void)validateAndSaveCriticalApplicationData 50.{ 51. 52.} 53. 54.- (void)handleException:(NSException *)exception 55.{ 56. [self validateAndSaveCriticalApplicationData]; 57. 58. UIAlertView *alert = 59. [[[UIAlertView alloc] 60. initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常", nil) 61. message:[NSString stringWithFormat:NSLocalizedString( 62. @"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n" 63. @"异常原因如下:\n%@\n%@", nil), 64. [exception reason], 65. [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]] 66. delegate:self 67. cancelButtonTitle:NSLocalizedString(@"退出", nil) 68. otherButtonTitles:NSLocalizedString(@"继续", nil), nil] 69. autorelease]; 70. [alert show]; 71. 72. CFRunLoopRef runLoop = CFRunLoopGetCurrent(); 73. CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); 74. 75. while (!dismissed) 76. { 77. for (NSString *mode in (NSArray *)allModes) 78. { 79. CFRunLoopRunInMode((CFStringRef)mode, 0.001, false); 80. } 81. } 82. 83. CFRelease(allModes); 84. 85. NSSetUncaughtExceptionHandler(NULL); 86. signal(SIGABRT, SIG_DFL); 87. signal(SIGILL, SIG_DFL); 88. signal(SIGSEGV, SIG_DFL); 89. signal(SIGFPE, SIG_DFL); 90. signal(SIGBUS, SIG_DFL); 91. signal(SIGPIPE, SIG_DFL); 92. 93. if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName]) 94. { 95. kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]); 96. } 97. else 98. { 99. [exception raise]; 100. } 101.} 102. 103.@end 104. 105.void HandleException(NSException *exception) 106.{ 107. int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); 108. if (exceptionCount > UncaughtExceptionMaximum) 109. { 110. return; 111. } 112. 113. NSArray *callStack = [UncaughtExceptionHandler backtrace]; 114. NSMutableDictionary *userInfo = 115. [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]]; 116. [userInfo 117. setObject:callStack 118. forKey:UncaughtExceptionHandlerAddressesKey]; 119. 120. [[[[UncaughtExceptionHandler alloc] init] autorelease] 121. performSelectorOnMainThread:@selector(handleException:) 122. withObject: 123. [NSException 124. exceptionWithName:[exception name] 125. reason:[exception reason] 126. userInfo:userInfo] 127. waitUntilDone:YES]; 128.} 129. 130.void SignalHandler(int signal) 131.{ 132. int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); 133. if (exceptionCount > UncaughtExceptionMaximum) 134. { 135. return; 136. } 137. 138. NSMutableDictionary *userInfo = 139. [NSMutableDictionary 140. dictionaryWithObject:[NSNumber numberWithInt:signal] 141. forKey:UncaughtExceptionHandlerSignalKey]; 142. 143. NSArray *callStack = [UncaughtExceptionHandler backtrace]; 144. [userInfo 145. setObject:callStack 146. forKey:UncaughtExceptionHandlerAddressesKey]; 147. 148. [[[[UncaughtExceptionHandler alloc] init] autorelease] 149. performSelectorOnMainThread:@selector(handleException:) 150. withObject: 151. [NSException 152. exceptionWithName:UncaughtExceptionHandlerSignalExceptionName 153. reason: 154. [NSString stringWithFormat: 155. NSLocalizedString(@"Signal %d was raised.", nil), 156. signal] 157. userInfo: 158. [NSDictionary 159. dictionaryWithObject:[NSNumber numberWithInt:signal] 160. forKey:UncaughtExceptionHandlerSignalKey]] 161. waitUntilDone:YES]; 162.} 163. 164.void InstallUncaughtExceptionHandler(void) 165.{ 166. NSSetUncaughtExceptionHandler(&HandleException); 167. signal(SIGABRT, SignalHandler); 168. signal(SIGILL, SignalHandler); 169. signal(SIGSEGV, SignalHandler); 170. signal(SIGFPE, SignalHandler); 171. signal(SIGBUS, SignalHandler); 172. signal(SIGPIPE, SignalHandler); 173.} 三:最后在AppDelegate中创建 [plain] view plaincopy01.- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 02. InstallUncaughtExceptionHandler(); 03. self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 04. // Override point for customization after application launch. 05. self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; 06. self.window.rootViewController = self.viewController; 07. [self.window makeKeyAndVisible]; 08. return YES; 09.}
0 0