[英]How to use NSSetUncaughtExceptionHandler to show exception message on UIView in Swift
[英]How should I use NSSetUncaughtExceptionHandler in Swift
在 Objective-C 中,我調用NSSetUncaughtExceptionHandler(&exceptionHandler)
方法來記錄異常。 它在 Swift 中是如何調用的?
從 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
s。 所以這將被捕獲:
let array = NSArray()
let elem = array.objectAtIndex(99)
注意:- 它不會捕獲任何 Swift 2 錯誤(來自throw
)或 Swift 運行時錯誤,因此不會捕獲:
let arr = [1, 2, 3]
let elem = arr[4]
使用 Swift 2,您可以將 Swift 函數和閉包作為 C 函數指針傳遞。 請參閱下面的 Martin R 的回答。
你不能,從 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)
以這種方式在重新打開后續應用程序時可以看到錯誤。
此代碼適用於 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()
})
}
編輯:代碼工作。 但是您需要在出錯后重新打開您的應用程序。
斯威夫特 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. 跟蹤控制台輸出,它會立即打印出您剛剛提出的異常,並從您提供的原因開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.