用Runtime中转发消息的方式解决服务器端返回NSNULL的问题
来源:互联网 发布:python re.compile用法 编辑:程序博客网 时间:2024/06/06 18:40
http://www.jianshu.com/p/7f937ed1e132
有时候服务器很烦不靠谱,老是不经意间返回null,所以在iOS端不得不校验它的类型等。譬如:返回的数组为null,首先得判断类型是不是NSArray 还得判断非空。
NSArray *products = data[@"省心宝"];if ([products isKindOfClass:[NSArray class]] && products.count > 0){ // TO DO}
这种问题一多,就会影响我们程序猿的心情,并且代码也变得冗余了,所以换种技巧solve it。
思路:重写NSNull的消息转发方法, 让他能处理这些异常的方法。
常见的几种类型为"",0,{},[]了。
所以,创建一个NSNull的分类 NSNull (InternalNullExtention)
具体实现如下:
.h文件
#import <Foundation/Foundation.h>@interface NSNull (InternalNullExtention)@end
.m文件
#import "NSNull+InternalNullExtention.h"#define NSNullObjects @[@"",@0,@{},@[]]@implementation NSNull (InternalNullExtention)+ (void)load{ @autoreleasepool { [self swizzleInstanceMethodWithClass:[NSNull class] originalSel:@selector(methodSignatureForSelector:) replacementSel:@selector(wt_methodSignatureForSelector:)]; [self swizzleInstanceMethodWithClass:[NSNull class] originalSel:@selector(forwardInvocation:) replacementSel:@selector(wt_forwardInvocation:)]; }}- (NSMethodSignature *)wt_methodSignatureForSelector:(SEL)aSelector{ NSMethodSignature *signature = [super methodSignatureForSelector:aSelector]; if (!signature) { for (NSObject *object in NSNullObjects) { signature = [object methodSignatureForSelector:aSelector]; if (!signature) { continue; } if (strcmp(signature.methodReturnType, "@") == 0) { signature = [[NSNull null] methodSignatureForSelector:@selector(wt_nil)]; } return signature; } return [self wt_methodSignatureForSelector:aSelector]; } return signature;}- (void)wt_forwardInvocation:(NSInvocation *)anInvocation{ if (strcmp(anInvocation.methodSignature.methodReturnType, "@") == 0) { anInvocation.selector = @selector(wt_nil); [anInvocation invokeWithTarget:self]; return; } for (NSObject *object in NSNullObjects) { if ([object respondsToSelector:anInvocation.selector]) { [anInvocation invokeWithTarget:object]; return; } } [self wt_forwardInvocation:anInvocation]; // [self doesNotRecognizeSelector:aSelector];}- (id)wt_nil{ return nil;}+ (void)wt_swizzleInstanceMethodWithClass:(Class)clazz originalSel:(SEL)original replacementSel:(SEL)replacement{ Method originMethod = class_getInstanceMethod(clazz, original); Method replaceMethod = class_getInstanceMethod(clazz, replacement); if (class_addMethod(clazz, original, method_getImplementation(replaceMethod), method_getTypeEncoding(replaceMethod)) { class_replaceMethod(clazz, replacement, method_getImplementation(originMethod), method_getTypeEncoding(originMethod)); } else { method_exchangeImplementations(originMethod, replaceMethod); }}@end
测试代码就不加了。
0 0
- 用Runtime中转发消息的方式解决服务器端返回NSNULL的问题
- iOS 用Runtime解决服务器返回NSNull问题
- Servlet中转发和重定向的路径问题
- Servlet中转发和重定向的路径问题
- Servlet中转发和重定向的路径问题
- 关于servlet中转发jsp的路径问题
- web中转发、重定向等问题的路径
- 服务器端返回的JSON字符串 怎样在 JS中转换成可访问的 JSON对象
- struts2中转发问题
- 解决Struts2中转换Date类型的问题
- vc6.0向VS2010中转换问题的解决
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- Servlet中转发和重定向的路径问题以及表单提交路径问题
- linux添加开机自启动脚本示例详解
- Elasticsearch Client 初始化方式以及清除数据方式
- 一个APP开发者的愤慨:为啥会有打包党和上传手机号
- nginx启动、重启、关闭
- Java 微服务框架 Redkale 入门介绍
- 用Runtime中转发消息的方式解决服务器端返回NSNULL的问题
- android源码下的jni开发
- Linux环境配置tomcat和jdk
- iClient for JavaScript VectorLayer详细使用指南
- WATER
- MyBatis 根据表结构自动生成代码, domain, dao, mapper 文件
- MySQL的存储引擎InnoDB间隙锁
- Swift学习-逻辑分支
- 自定义adapter getview()重复执行(超出应执行次数)