我们在平时项目做功能的时候,经常会遇到崩溃的情况。如果是我们在开发测试阶段,我们可以找到原因修复。但是遇到已经上线,出现这种问题。要么使用JSPatch
进行热修复,但是使用热修复修复苦只有写的人知道。
本来就是一个方法一个单词写错,一个值没做异常处理,就要重写整个方法。对于像我这样根本不懂JS
语法和不精通JSPatch
的人来说,真的是蓝瘦,香菇。
最近写的项目用Swift
语法进行编写的,对于之前我们在Object-C
中NSError**
类型的指针标识遇到了什么错误,现在转成Swift
方法直接进行throws
进行抛异常。
这样我们就必须使用Do Catch
进行捕获异常了,我觉得苹果这样做真的挺好的。
比如我刚刚写的项目,就用上了,感觉用完顿时高大上了许多。
import Cocoa
enum OFileMagerImportError:Error {
case cannel //点击了取消的按钮
case error(message:String)
}
class OFileManger: NSObject {
/*
* 导入配置文件
* return 返回一个数组对象 可能返回为空
*/
class func importAction() throws -> [Any] {
let openPannel = NSOpenPanel()
openPannel.allowedFileTypes = ["ork"]; // 只允许读取.ork的文件类型
openPannel.allowsMultipleSelection = false // 设置不允许多选
let buttonIndex = openPannel.runModal()
guard buttonIndex == NSFileHandlingPanelOKButton else {
throw OFileMagerImportError.cannel
}
guard openPannel.urls.count > 0 else {
throw OFileMagerImportError.error(message:"你还没有选择任何的配置文件!")
}
guard let fileName = openPannel.urls.first else {
throw OFileMagerImportError.error(message:"你还没有选择任何的配置文件!")
}
guard let jsonData = try? Data(contentsOf: fileName) else {
throw OFileMagerImportError.error(message:"读取文件内容失败!")
}
guard let jsonObj = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) else {
throw OFileMagerImportError.error(message:"配置文件内容不是一个JSON文本!")
}
guard let configList:[Any] = jsonObj as? [Any] else {
throw OFileMagerImportError.error(message:"配置文件内容不是一个数组对象!")
}
return configList
}
}
调用的时候我们可以这么写。
@IBAction func importAction(_ sender: Any) {
do {
let configList:[Any] = try OFileManger.importAction()
print(configList)
} catch OFileMagerImportError.error(let message) {
OAlertMessage.alert(message: message)
} catch {
print("抛出了其他不给用户看到的错误!")
}
}
我们就可以做一些错误的处理。但是只是这样,我心里面还不是十分强烈想用。
后来线上的App
在双11那天晚上突然出现打不开崩溃的情况,在外面准备吃饭庆祝的强行喊回去解决问题。
回去觉得应该是那里崩溃了吧,应该也是十分的容易解决。
后来发现因为接口因为最近上线的功能出问题了,就回滚了代码。导致之前一些接口的字段没有返回,恰好那个接口没有用Model
进行映射,所以就出现崩溃了。
经理一直问这个接口回滚好几天了为啥突然出问题了,原来是接口做了缓存,会根据后台返回是否需要更新才会重新的请求接口。
双11那天正好运维更新了数据,导致接口重新请求,少了字段导致崩溃。最后让后台强行把拿两个字段返回,最快的解决问题。
虽然让后台加上了字段,但是我觉得我们App
这里没有做好兼容,才导致这一次事故。幸亏没影响多久,再说客户都是外国人,那个时间还没睡醒。
导致的崩溃自然不止这些,但是这些占据了崩溃里面大部分,前三个我们可以做一下异常处理,最后一个最好还是让后台规范起来,这是长远之际。或者使用Model
进行映射。
if else
判断Try catch
进行处理虽然两个都要写很多的代码,if else
的代码更加优美一点,但是就怕有一种情况你没写出来。觉得最好的办法还是用try catch
进行。
@try
,@catch
,@throw
,和 @finally
。这四个关键词进行异常处理。
我们看一下常见的一个数组越界的例子:
NSArray *tests = @[];
NSNumber *num = tests[0];
我们不用运行就可以知道这个地方会崩溃,因为我们初始化的数组是空的。但是我们强行取一个元素,导致崩溃。
假设我们现在用上了try catch
的代码,会如何呢。
NSArray *tests = @[];
@try {
NSNumber *num = tests[0];
} @catch (NSException *exception) {
NSLog(@"%@",exception.userInfo);
} @finally {
NSLog(@"我做一些必须的处理");
}
经过测试,这个代码会在Debug
的时候断点,但是强行运行还是可以运行的。但是在Release
发布之后运行完全没有任何的影响。
虽然我们平时写代码上面,不可能让所有出现异常的地方写上这样的代码。但是对着我们的经验,我们对于一眼就知道会出崩溃的地方加上,还是能让线上的应用少出很多问题的。
关于Try catch
的资料可以查看下面资料:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有