簡體   English   中英

我應該如何在 Swift 中使用 NSSetUncaughtExceptionHandler

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM