NullSafe 学习

作为处理向 NSNull 发送消息导致的崩溃处理框架,NullSafe 应该是最轻量简洁的了,算起来 50行 代码不算就解决了开发中的NSNull异常的棘手问题。

问题的出现于处理基于Objective-C语言的特性:

  • OC 中方法调用其实就是向对象发送消息
  • 发送出去的消息必须被处理
  1. NSNull 添加 Category, 这样就无需用代码引入,系统检测到对 NSNull 发送任何消息都会自动调用 NullSafe 类,如果不想使用,可以用开关关掉
#define NULLSAFE_ENABLED 0
  1. 接一个 Xcode 警告⚠️消除
#pragma clang diagnostic ignored "-Wgnu-conditional-omitted-operand"

看解释是消除代码中使用了类似三元运算符?:而没有添加中间变量的warning,但细看代码,并没有类似的逻辑。
其他关联 ignored 可以参考 使用 #pragma 阻止一些warnings

  1. iOS 中对方法的调用,其实就是向目标对象发送各种消息, 造成程序崩溃的主要原因就是因为目标对象无法处理接收到的消息,最后抛出 doseNotRecognizeSelector 异常。结合 runtime,在目标对象无法处理接收到的消息的时候,还有补救措施,例如 Fast ForwardNormal Forward, NullSafe 正是利用了消息转发过程的逻辑,跳过 动态方法解析获取备用接收者 的过程,直接处理消息转发的最后一步。这一步的关键就是重写
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector

这个方法,从而获取到 NSMethodSignature 对象,只要获取到的 signature != nil 就可以使用备用调用者来处理此消息。

- (void)forwardInvocation:(NSInvocation *)invocation

这一步处理的目的是对消息进行处理,也就是文章开头提到的第二点,所有发送出去的消息必须要处理才可以。

  1. 把新消息对象设置为 nil 因为对 nil 发送任何消息都是可以的,这里就把完成了对消息的处理,而不会造成程序崩溃。

  2. 获取处理该消息的新类都是 NSObject 的子类,如果有可变对象,则用可变对象,若没有则用本对象。

for (Class someClass in @[
            [NSMutableArray class],
            [NSMutableDictionary class],
            [NSMutableString class],
            [NSNumber class],
            [NSDate class],
            [NSData class]
        ])

一般来说

MutableClass : Class

这样对于同一个类型的类来说,只需要 MutableClass 即可,如果 MutableClass 无法处理此消息,那么 Class 也无法处理。

  1. 省去了 .h 文件,最大化的让代码变轻
    这种方式倒是不常见,为此自己仿写一个实验下效果,
  • 建立一个 NSString+PrintCategory;
  • 删掉 .h 文件;
  • 删掉 .m 中的 #import "NSString+Print.h"
  • 加入类库引用 #import <Foundation/Foundation.h>
  • 随便添加个类方法和实例方法
    完整代码(NSString+Print.m)
#import <Foundation/Foundation.h>

@implementation NSString (Print)

+ (void)print:(NSString *)str {
    NSLog(@"😃 %@", str);
}

- (void)print:(NSString *)str {
    NSLog(@"😁 %@", str);
}

@end

在其他文件中测试该方法,由于NSString 和 父类 NSObject 中都不含有

- (void) print;  //不含有此实例方法
+ (void) print; //不含有此类方法

所以添加的方法只能在运行阶段识别,所以在编译时期无法识别该方法,导致编译阶段无法通过


借助 msg_send 函数,手动发送此消息验证

((void (*)(id, SEL, id))objc_msgSend)([NSString class], @selector(print:), str);

当然此时会报 Undeclared selector 'print:'warning 不过不影响编译.

最后可以测试通过


可见在无需与其他文件进行交互的前提下,单独的 .m 文件是完全可行的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容

  • 前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。 目录:iOS-面试题-OC基础篇 (1) - (84...
    麦穗0615阅读 4,243评论 0 33
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,607评论 0 15
  • 一、深复制和浅复制的区别? 1、浅复制:只是复制了指向对象的指针,即两个指针指向同一块内存单元!而不复制指向对象的...
    iOS_Alex阅读 1,349评论 1 27
  • 张海萍 焦点网络中级八期 山西晋中 坚持分享第332天 2019年1月20日 周日 何为讲师?我想讲师首先是学习...
    小海儿2阅读 1,040评论 0 1
  • FutureTask介绍FutureTask是一种可以取消的异步的计算任务。它的计算是通过Callable实现的,...
    先生zeng阅读 149评论 0 1