ios开发中的容错处理示例详解

前言

后台服务器返回给客户端的值有时会是null,有时会是"<null>",直接赋值并进行后续操作有时会导致崩溃。 之前的处理方式都是尽量让后台服务器返回数据时不返回null或者是"<null>",但是他们还是时不时返回这些数据,所以app时不时就会出现闪退现象。一出现这种问题,调试后发现是他们返回null或者是"null"的数据类型,因为是线上的问题,所以让他们直接在后台将出现问题的字段进行处理就好了。久而久之,发现这种处理方式并不可取,觉得应该在app端应该做些容错处理,因此就有了这篇文章,接下来和我看一下有哪些容错处理的方式。

具体如下:

写个工具类,判断处理每个字段是不是[NSNull null]对象,或者判断是不是isEqual:@"<null>";

用AFNetworking作为网络请求的话,可以设置以下变量为YES;

// AFURLResponseSerialization.h
/**
 Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`.
 */
@property (nonatomic, assign) BOOL removesKeysWithNullValues;

大牛写了个NSNull分类:源码地址 (本地下载)用法是直接将该类拖到项目中即可,NullSafe思路:在运行时操作,把空值置换为nil,而向nil指针发送消息是不会崩溃的。

我这里主要说的是第三种解决方案,我将该项目从github上下载到本地,然后拖到项目中后,本以为这样就可以解决问题了,因为自己写了个测试demo,给UILabel赋值null,没有拖进去该库时直接崩溃了,将该库拖进项目后发现项目正常运行。所以就认为可以一劳永逸了,但是在项目中测试时,发现仍然出现崩溃的现象,打断点调试后,发现后台传回的数据是"<null>",而NSNull分类中只是判断了数据是否是NSNull类型,如果是NSNull类型,就将其设置为nil,然而后台传回的数据是"<null>",它并不是NSNull类型,所以仍然会崩溃,所以我在该项目的基础上,加了个是否等于<null>的判断,如果条件成立,则将其设置为nil,这样就可以避免后台传回我们不想要的数据而导致崩溃的问题了,修改后的代码如下:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
 //look up method signature
 NSMethodSignature *signature = [super methodSignatureForSelector:selector];
 if ([signature isEqual:@"<null>"]) {

 signature = nil;

 }else if ([signature isKindOfClass:[NSNull class]]) {

 signature = nil;

 }else if (!signature) {

 //check implementation cache first
 NSString *selectorString = NSStringFromSelector(selector);
 signature = signatureCache[selectorString];
 if (!signature)
 {
  @synchronized([NSNull class])
  {
  //check again, in case it was resolved while we were waitimg
  signature = signatureCache[selectorString];
  if (!signature)
  {
   //not supported by NSNull, search other classes
   if (signatureCache == nil)
   {
   if ([NSThread isMainThread])
   {
    cacheSignatures();
   }
   else
   {
    dispatch_sync(dispatch_get_main_queue(), ^{
    cacheSignatures();
    });
   }
   }

   //find implementation
   for (Class someClass in classList)
   {
   if ([someClass instancesRespondToSelector:selector])
   {
    signature = [someClass instanceMethodSignatureForSelector:selector];
    break;
   }
   }

   //cache for next time
   signatureCache[selectorString] = signature ?: [NSNull null];
  }
  }
 }
 }
 return signature;
}

当然也可以去github下载,源码地址 (本地下载),但是需要加上下图所示的代码:

需要添加的代码截图

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • IOS UIWebView获取404、504等错误问题解决方案

    UIWebView获取404.504等错误码 问题描述     在使用webview时,会存在这么一个问题:     如果访问服务器返回异常,比如404.504这样的错误,需要在native端展示特定的图片和文案(404.504酱紫的错误码有些不美观).那么,问题就来了,怎样才能知道webview的访问出错了,是什么错??? 问题分析     从webview发起请求之后,能够查看webview加载状态的就是它的代理了,所以就从各个代理方法着手分析. // webview被指示加载内容时调用,返

  • IOS 签名错误codesign failed with exit code 1解决方法

    IOS 签名错误 前日,Macbook的硬盘不幸挂了,于是将开发环境迁移到Mac Mini下.大家知道,对于Xcode来说,最麻烦的就是各种证书.ProvisioningProfile的配置问题.将原来的各种开发证书和.p12证书导入到mini上,接下来就碰到了各种莫名其妙的问题.先是无法development(可以debug),发现是证书导错了(没有用Agent证书,只有Agent可以发布).于是制作证书请求,重新下载证书. 等到部署的问题解决后,又发现无法调试--真机可以,但模拟器不行,一进

  • IOS 出现错误reason: image not found的解决方案

    IOS 出现错误reason: image not found的解决方案 在制作framework时遇到真机运行时导致的reason: image not found允许崩溃的问题,下面是我的解决方案: 首先我们分析一下出现这种情况的原因,原因就是framework找不到镜像了,也就是在真机运行是没有找到对应的framework包,在网上找的一些办法将框架引用从Required 变为Optional ,根本就是治标不治本,等到运行到这个framework的代码是也会崩溃,我们需要做的是将这个fr

  • iOS 报clang: error: no input files错误的解决方法

    前言 本文主要给大家介绍了关于解决iOS 报clang: error: no input files错误的方法,这是最近在工作中遇到的一个问题,发现网上的相关解决方法几乎没有,所以将自己的解决过程分享出来,下面话不多说了,来一起看看详细的介绍吧. 一.概念 1.错误描述: ios  clang: error: no input files 2.如图: 二.解决方法 1.文字描述 clang: error: no input files这个问题一般是因为你删除或者移动了某一个文件,但是在你的编译资

  • IOS 上架后出现90034代码错误问题解决

      iOS上架90034问题解决   开发完成的APP,我们当然要上传到AppStore里面了,这可是我们心血的结晶. 可是,就当我们兴奋之余,却发现我们的App根本无法上传到AppStore.我们百度.谷歌了N种方法,就像我这种逗逼,整整试了不下15次,还是不行.可是,一个偶然的操作,居然成功了,然后又连试几发,真是百试不爽,赶紧拿出来分享.遇到这种问题的小伙伴们,一定要注意看了. 1.不成功的方法: 百度谷歌了好久,基本都不这种回答:先本地钥匙串的证书全删了,然后把开发者帐号里的证书也全删了

  • 使用iOS推送时警告错误的解决方法

    在使用iOS推送时,出现下面错误: **[1412:60b] You've implemented -[<UIApplicationDelegate> application:performFetchWithCompletionHandler:], but you still need to add "fetch" to the list of your supported UIBackgroundModes in your Info.plist. **[1412:60b]

  • iOS内存错误EXC_BAD_ACCESS的解决方法

    iOS开发,最郁闷的莫过于程序毫无征兆地就崩溃了,用bt命令打出调用栈,给出的是一堆系统EXC_BAD_ACCESS的信息,根本没办法定位问题出现在哪里. 首先说一下 EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作.举一个简单的例子来说明吧,首先看一段Java代码: 复制代码 代码如下: public class Test{ public static void main(String[] args){ String s = "

  • ios开发中的容错处理示例详解

    前言 后台服务器返回给客户端的值有时会是null,有时会是"<null>",直接赋值并进行后续操作有时会导致崩溃. 之前的处理方式都是尽量让后台服务器返回数据时不返回null或者是"<null>",但是他们还是时不时返回这些数据,所以app时不时就会出现闪退现象.一出现这种问题,调试后发现是他们返回null或者是"null"的数据类型,因为是线上的问题,所以让他们直接在后台将出现问题的字段进行处理就好了.久而久之,发现这种

  • iOS开发探索多线程GCD任务示例详解

    目录 引言 同步任务 死锁 异步任务 总结 引言 在上一篇文章中,我们探寻了队列是怎么创建的,串行队列和并发队列之间的区别,接下来我们在探寻一下GCD的另一个核心 - 任务 同步任务 void dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block); 我们先通过lldb查看其堆栈信息,分别查看其正常运行和死锁状态的信息 我们再通过源码查询其实现 #define _dispatch_Block_

  • iOS开发探索多线程GCD队列示例详解

    目录 引言 进程与线程 1.进程的定义 2.线程的定义 3. 进程和线程的关系 4. 多线程 5. 时间片 6. 线程池 GCD 1.任务 2.队列 3.死锁 总结 引言 在iOS开发过程中,绕不开网络请求.下载图片之类的耗时操作,这些操作放在主线程中处理会造成卡顿现象,所以我们都是放在子线程进行处理,处理完成后再返回到主线程进行展示. 多线程贯穿了我们整个的开发过程,iOS的多线程操作有NSThread.GCD.NSOperation,其中我们最常用的就是GCD. 进程与线程 在了解GCD之前

  • IOS 开发中画扇形图实例详解

    IOS 开发中画扇形图实例详解 昨天在做项目中,遇到一个需要显示扇形图的功能,网上搜了一下,发现code4app里面也没有找到我想要的那种类似的效果,没办法了,只能自己学习一下如何画了. 首先我们需要了解一个uiview的方法 -(void)drawRect:(CGRect)rect 我们知道了这个方法,就可以在自定义UIView的子类的- (void)drawRect:(CGRect)rect里面绘图了,关于drawrect的调用周期,网上也是一找一大堆,等下我会整理一下,转载一篇供你们参考.

  • java开发RocketMQ生产者高可用示例详解

    目录 引言 1 消息 1.1 topic 1.2 Body 1.3 tag 1.4 key 1.5 延迟级别 2 生产者高可用 2.1 客户端保证生产者高可用 2.1.1 重试机制 2.1.2 客户端容错 2.2 Broker端保证生产者高可用 引言 前边两章说了点基础的,从这章开始,我们挖挖源码.看看RocketMQ是怎么工作的. 首先呢,这个生产者就是送孩子去码头的家长,孩子们呢,就是消息了. 我们看看消息孩子们都长啥样. 1 消息 public class Message implemen

  • IOS开发基础之二维数组详解

    IOS开发基础之二维数组详解 首先我们知道OC中是没有二维数组的,二维数组是通过一位数组的嵌套实现的,但是别忘了我们有字面量,实际上可以和C/C++类似的简洁地创建和使用二维数组.这里总结了创建二维数组的两种方法以及数组的访问方式. 通过字面量创建和使用二维数组(推荐) // 1.字面量创建二维数组并访问(推荐) NSArray *array2d = @[ @[@11,@12,@13], @[@21,@22,@23], @[@31,@32,@33] ]; // 字面量访问方式(推荐) NSLog

  • Flutter 中 Dart的Mixin示例详解

    原文在这里.写的不错,推荐各位看原文. 这里补充一下Mixin的定义: 只要一个类是继承自Object的而且没有定义构造方法,那么这个类可以是一个Mixin了.当然,如果你想让mixin的定义更加的清晰,可以使用mixin关键字开头来定义.具体请参考这里 原文截图体会一下风格. 正文 在经典的面向对象编程语言里一定会有常规的类,抽象类和接口.当然,Dart也有它自己的接口,不过那是另外的文章要说的.有的时候阴影里潜伏者另外的野兽:Mixin!这是做什么的,如何使用?我们来一起发现. 没有mixi

  • Java开发中为什么要使用单例模式详解

    一.什么是单例模式? 单例设计模式(Singleton Design Pattern)理解起来非常简单.一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式. 二.实战案例一:处理资源访问冲突 我们先来看第一个例子.在这个例子中,我们自定义实现了一个往文件中打印日志的 Logger 类.具体的代码实现如下所示: public class Logger { private FileWriter writer; public Logger() {

  • Java中的反射机制示例详解

    目录 反射 什么是Class类 获取Class实例的三种方式 通过反射创建类对象 通过反射获取类属性.方法.构造器 更改访问权限和实例赋值 运用场景 反射 反射就是把Java类中的各个成分映射成一个个的Java对象.即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法:对于任意一个对象,都能调用它的任意一个方法和属性.这种动态获取信息及动态调用对象方法的功能叫Java的反射机制 每一个Java程序执行必须通过编译.加载.链接和初始化四个阶段 1.编译:将.java.文件编译成字节码.

  • Android开发Kotlin实现圆弧计步器示例详解

    目录 效果图 定义控件的样式 自定义StepView 绘制文本坐标 Android获取中线到基线距离 效果图 定义控件的样式 看完效果后,我们先定义控件的样式 <!-- 自定义View的名字 StepView --> <!-- name 属性名称 format 格式 string 文字 color 颜色 dimension 字体大小 integer 数字 reference 资源或者颜色 --> <declare-styleable name="StepView&q

随机推荐