【发布时间】:2013-04-18 14:19:16
【问题描述】:
据我了解,EXC_BAD_ACCESS 发生在您尝试访问坏内存时(如果我错了,请随时纠正我)?
有没有办法像在try-catch 中那样在Java 中捕获它以防止应用程序完全失败?
【问题讨论】:
标签: iphone ios objective-c exc-bad-access
据我了解,EXC_BAD_ACCESS 发生在您尝试访问坏内存时(如果我错了,请随时纠正我)?
有没有办法像在try-catch 中那样在Java 中捕获它以防止应用程序完全失败?
【问题讨论】:
标签: iphone ios objective-c exc-bad-access
如果你想用闭包捕获或处理崩溃,你可以使用https://github.com/dhatbj/SignalRecovery
C 代码 func 宏在 swift 中不可用,不能直接调用函数(signal_try、signal_catch、signal_end) 这是一个如何将闭包作为函数参数传递的示例。
首先我们需要将完成块传递给 C 代码并返回信号错误。
将此代码添加到 signal_recovery.h:
const char* signalTry(void (*block)(void));
将此代码添加到 signal_recovery.c:
const char* signalTry(void (*block)(void)) {
const char* signalName = "";
signal_try(label0) {
block();
}
signal_catch(label0) {
signalName = signal_name(signal_info()->si_signo);
}
signal_end(label0)
return signalName;
}
在 swift 代码中,您需要调用 C 函数 signalTry 并将闭包作为参数传递给它:
import // C files
class ExceptionsHandler {
private static var isReady = false
init() {
if !Self.isReady {
Self.isReady = true
signal_catch_init()
}
}
private func cFunction(_ block: @escaping @convention(block) () -> Void) -> (@convention(c) () -> Void) {
return unsafeBitCast(imp_implementationWithBlock(block), to: (@convention(c) () -> Void).self)
}
func execute(_ block: @escaping () -> Void) throws {
let cBlock: @convention(c) () -> Void = cFunction {
block()
}
let error = signalTry(cBlock)
if let error = error, !String(cString: UnsafePointer<CChar>(error)).isEmpty {
print("Catched signal \(String(cString: UnsafePointer<CChar>(error)))")
throw \\ error or exception
}
}
}
当闭包 block() 中发生错误 EXC_BAD_ACCESS 时,此 C 函数将跳过它,您将捕获它而不会崩溃。
像这样:
try self.exceptionsHandler.execute {
let a = 3
let b = 0
let c = a / b
// or
let testArray: [Int] = []
let number = testArray[100]
}
【讨论】:
新的 C 库SignalRecovery 可以使程序能够从操作系统异常中恢复,例如EXC_BAD_ACCESS。
可以在IOS/MacOS/Linux中使用。
示例代码:
signal_try(label) {
// Add your code need try.
int* ptr = NULL;
*ptr = 0;
}
signal_catch(label) {
// Add your code to process exceptions, or do nothing.
siginfo_t* info = signal_info();
}
signal_end(label)
// Continue run
【讨论】:
可以使用 try catch,但您首先需要知道导致问题的原因。您可以为当前构建启用 NSZombie 以捕获错误并消除需要。编辑当前方案,启用 NSZombie。
【讨论】:
您有时可以使用信号处理程序在main 中捕获它。但是,除了记录一些东西之外,它不允许您做太多事情。
【讨论】:
不; EXC_BAD_ACCESS 表示事情已经严重脱轨。您的程序正在尝试访问无效的内存地址。 IE。内存已损坏且无法恢复。
这可能是内存管理问题。如果您可以重现该问题,请打开 NSZombies 并查看会发生什么。或者在这里发布回溯。
请注意,try-catch 样式的异常在 iOS/Cocoa 中也是不可恢复的。异常不能用于可恢复的错误处理。这就是 NSError 的用途。
【讨论】:
@try / @catch捕获,但其他的可以;我认为后者是“可恢复的”,就像任何其他具有异常捕获机制的现代语言一样。