在Objective-C,我调用NSSetUncaughtExceptionHandler(&exceptionHandler)
方法来记录异常。它是如何在Swift中调用的?
答案 0 :(得分:47)
从Swift 2(Xcode 7)开始,您可以传递Swift函数/闭包 采用C函数指针的参数。从Xcode 7发行说明:
对C函数指针的本机支持:带函数的C函数 可以使用闭包或全局函数调用指针参数, 限制,关闭不得捕获其任何一个 当地情况。
所以这个编译和工作:
func exceptionHandler(exception : NSException) {
print(exception)
print(exception.callStackSymbols)
}
NSSetUncaughtExceptionHandler(exceptionHandler)
或者使用“内联”封口:
NSSetUncaughtExceptionHandler { exception in
print(exception)
print(exception.callStackSymbols)
}
这与相应的Objective-C代码完全相同:
它捕获了其他未被捕获的NSException
。
所以这将被抓住:
let array = NSArray()
let elem = array.objectAtIndex(99)
注意: - 它不捕获任何Swift 2错误(来自throw
)或Swift运行时错误,因此未捕获:
let arr = [1, 2, 3]
let elem = arr[4]
答案 1 :(得分:13)
使用Swift 2,您可以将Swift函数和闭包作为C函数指针传递。 See Martin R's answer below
您不能使用Xcode 6 beta 6。
Swift确实支持传递函数指针,但它们的处理方式与非透明指针非常相似。你既不能定义一个指向Swift函数的C函数指针,也不能在Swift中调用C函数指针。
这意味着你从Swift调用NSSetUncaughtExceptionHandler()
,但处理程序必须在Objective-C中实现。你需要一个像这样的头文件:
volatile void exceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *exceptionHandlerPtr;
在实施中,你需要这样的东西:
volatile void exceptionHandler(NSException *exception) {
// Do stuff
}
NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHandler;
在Swift桥接头中导入头文件后,您可以照常设置异常处理程序:
NSSetUncaughtExceptionHandler(exceptionHandlerPtr)
答案 2 :(得分:2)
以这种方式重新打开后续应用程序时可以看到的错误。
此代码适用于swift 4。
加入didFinishLaunchingWithOptions()
:
NSSetUncaughtExceptionHandler { exception in
print("Error Handling: ", exception)
print("Error Handling callStackSymbols: ", exception.callStackSymbols)
UserDefaults.standard.set(exception.callStackSymbols, forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
}
并且代码添加在fistViewController viewLoad()
// ERROR ExceptionHandler
if let exception = UserDefaults.standard.object(forKey: "ExceptionHandler") as? [String] {
print("Error was occured on previous session! \n", exception, "\n\n-------------------------")
var exceptions = ""
for e in exception {
exceptions = exceptions + e + "\n"
}
AlertFunctions.messageType.showYesNoAlert("Error was occured on previous session!", bodyMessage: exceptions, {
}, no: {
UserDefaults.standard.removeObject(forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
})
}
编辑: 代码工作。但是您需要在出错后重新打开应用程序。
答案 3 :(得分:0)
快捷键5:
1。将此方法添加到AppDelegate:
func storeStackTrace() {
NSSetUncaughtExceptionHandler { exception in
print(exception)
// do stuff with the exception
}
}
2。从didFinishLaunchingWithOptions调用此方法,并在
之后立即引发异常 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
storeStackTrace()
let exception = NSException(name: NSExceptionName(rawValue: "arbitrary"), reason: "arbitrary reason", userInfo: nil)
exception.raise()
}
3。跟进控制台输出,它将立即从您提供的原因开始打印出刚提出的异常。