在移动端APP开发中,崩溃率是一个衡量APP性能的一个很重要的指标。常见的崩溃有服务器返回数据崩溃、内存泄漏崩溃、多个子线程同时操作ui崩溃。
服务器返回数据异常崩溃
服务器返回的数据通常有数字、字符串、 数组和字典四种类型,倘若服务器返回异常数据null,程序有可能把它当做以上四种中的其中一种处理,必会导致 unrecognized selector 崩溃。
NSNull 分类
iOS 会把收到的 json 值 null 解析成 NSNull 字段,这时候可以在 NSNull 分类中转发以上四种类型的消息,防止崩溃。
#define JsonObjects @[@"",@0,@{},@[]]
@implementation NSNull (safe)
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (![self respondsToSelector:aSelector]) {
// 没有实现的方法,从四种常见数值对象中查找
for (id jsonObj in JsonObjects) {
if ([jsonObj respondsToSelector:aSelector]) {
NSLog(@"消息响应对象用%@代替",[jsonObj class]);
return jsonObj;
}
}
}
return [super forwardingTargetForSelector:aSelector];
}
@end
测试方法如下:
-(void)test1{
NSDictionary *dict = [NSNull null];
[dict objectForKey:@"12"];
}
NSNumber 等的分类
另外,对于约定好服务器返回字符串类型的,结果却返回了数值类型,在给NSNumber对象发送NSString 类型的消息时,可以在 NSNumber 、NSString、NSArray、NSDictionary 分类中按照以上方式转发消息。
#define JsonObjects @[@"",@0,@{},@[]]
@implementation NSNumber (safe)
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (![self respondsToSelector:aSelector]) {
// 没有实现的方法,从四种常见数值对象中查找
for (id jsonObj in JsonObjects) {
if ([jsonObj respondsToSelector:aSelector]) {
NSLog(@"消息响应对象用%@代替",[jsonObj class]);
return jsonObj;
}
}
}
return [super forwardingTargetForSelector:aSelector];
}
@end
测试方法如下:
-(void)test2{
NSString *num = @(12);
num = [num stringByAppendingString:@"元"];
NSLog(@"%@",num);
}