崩溃检测迅速 [英] Crash detect swift

查看:53
本文介绍了崩溃检测迅速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NSSetUncaughtExceptionHandler仅捕获Objective-C异常.我只需要捕捉迅速的异常.有可能吗?

NSSetUncaughtExceptionHandler捕获了这一点.让arr = NSArray()让x = arr [4]

我也想抓住这个崩溃.让数字:整数?= nil let val =数字!

解决方案

我在上面的评论中已经提到

Swift不处理异常,它处理错误,因此,当对 let x = arr [4] 使用swift的try catch块时,您将无法捕获异常(其数组超出范围)例外,不是错误.)

正如Vadian指出的那样,Swift鼓励您捕获并解决这些异常,而不是在运行时捕获它们.

话虽这么说,在某些情况下,您必须显式处理异常,例如您正在处理用Objective-C编写的第三方框架,并且可能引发异常,或者您正在处理某些iOS API,仍然在Objective-C运行时中运行,并且在这种情况下会引发异常,在目标C中拥有自己的has方法并使用块/闭包向其传递swift语句并在Objective-C try catch块中执行它们很方便,>

如何做到?

在您的swift项目中添加一个Objective-C文件,它会询问您是否还创建桥接头文件,说是的,如图所示更新.h和.m文件

ExceptionCatcher.h

  #import< Foundation/Foundation.h>@interface ExceptionCatcher:NSObject+(void)catchExceptionIfAny:(void(^)(void))executeCodeBlock withCompletion:(void(^)(NSException *))完成;@结尾 

ExceptionCatcher.m

  #import< Foundation/Foundation.h>#import" ExceptionCatcher.h"@implementation ExceptionCatcher:NSObject+(void)catchExceptionIfAny:(void(^)(void))executeCodeBlock withCompletion:(void(^)(NSException *))完成{@尝试 {executeCodeBlock();}@catch(NSException * exception){NSLog(@%@",exception.description);完成(例外);}}@结尾 

最后,使用

更新桥接头文件

  #import" ExceptionCatcher.h" 

然后进入快速文件并将其用作

 令x = NSArray()ExceptionCatcher.catchExceptionIfAny({[weak self] in令a = x [4]debugPrint(a)}){(例外)在如果让e =例外{debugPrint(e.description)}} 

您显然可以看到x [4]应该以数组超出范围的异常结束,现在将捕获崩溃而不是崩溃的异常,并返回到您的完成块.

上面的代码有效,因为x声明为 NSArray ,如果您使用 x = [1,2,3] NSObject >您将创建Swift Array的实例,显然swift数组不会引发异常.因此,使用此方法时请务必小心.

这不是捕获所有 Exceptions 的变通办法,因此应谨慎使用(仅在避免这种情况的情况下),这是一个过大的技巧,但对于此用例来说是不必要的

NSSetUncaughtExceptionHandler catches only Objective-C exceptions. I need to catch only swift exceptions. Is it possible?

NSSetUncaughtExceptionHandler catches this one. let arr = NSArray() let x = arr[4]

I also want to catch this crash. let number: Int? = nil let val = number!

解决方案

As I already mentioned in my comment above

Swift does not deal with exception, it deals with error, hence when you use try catch block of swift for let x = arr[4] you cant catch the exceptions (Its array out of bound exception not an error).

As Vadian also pointed out Swift encourages you to catch and solve those exceptions rather than catching them at run time.

That being said, there might be scenarios when you have to deal with exceptions explicitly, example you are dealing with third party framework which is written in Objective-C and might throw an exception or you might be dealing with certain iOS API which still runs in Objective-C runtime and throws exception in such cases, its handy to have a have method of your own in objective C and pass swift statements to it using block / closure and execute them inside Objective-C try catch block,

How can you do it?

Add an Objective-C file to your swift project, it will ask you should it create bridging header as well, say yes, update your .h and .m files as shown

ExceptionCatcher.h

#import <Foundation/Foundation.h>

@interface ExceptionCatcher : NSObject
+ (void)catchExceptionIfAny: (void(^)(void)) executeCodeBlock withCompletion: (void (^)(NSException *)) completion;
@end

ExceptionCatcher.m

#import <Foundation/Foundation.h>
#import "ExceptionCatcher.h"

@implementation ExceptionCatcher : NSObject

+ (void)catchExceptionIfAny: (void(^)(void)) executeCodeBlock withCompletion: (void (^)(NSException *)) completion {
    @try {
        executeCodeBlock();
    }
    @catch (NSException *exception) {
        NSLog(@"%@", exception.description);
        completion(exception);
    }
}

@end

Finally, update your bridging header file with

#import "ExceptionCatcher.h"

And come to swift file and use it as

        let x = NSArray()
        ExceptionCatcher.catchExceptionIfAny({[weak self] in
            let a = x[4]
            debugPrint(a)
        }) { (exception) in
            if let e = exception {
                debugPrint(e.description)
            }
        }

As you can see obviously x[4] should end up with array out of bound exception, now instead of crashing exception will be captured and returned to your completion block.

The code above works because x is declared as NSArray which is extended form NSObject if you use x = [1,2,3] you will be creating an instance of Swift Array and obviously swift array wont throw exception. So be very careful when you use this method.

This is not a work around to catch all sort of Exceptions and should be used sparingly (only in cases when avoiding it is impossible) This is an overkill and unnecessary for this usecase however

这篇关于崩溃检测迅速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆