第31月第17天 resolveInstanceMethod
1.
#import "UIView+Test.h"
#import <objc/runtime.h> @implementation UIView (Test) + (BOOL)resolveInstanceMethod:(SEL)sel {
return NO;
} - (id)forwardingTargetForSelector:(SEL)aSelector {
// NSString *sel = NSStringFromSelector(aSelector); { //
Class class = objc_allocateClassPair(NSClassFromString(@"NSObject"),"AvoidCrashTarget",);
class_addMethod(class, aSelector, class_getMethodImplementation([self class], @selector(avoidCrashAction)), "@@:"); id tempObject = [[class alloc] init];
return tempObject;
} return [super forwardingTargetForSelector:aSelector];
} - (NSObject *)avoidCrashAction {
return nil;
} @end
在Objective-C中,在调用对象的某个方法时,其实是在向这个对象发送消息。系统会查看这个对象能否接收该消息,如果不能,则会进行消息转发,消息转发最多三个步骤(注:如果前一步成功处理了消息,那么就不会走到下一步):
调用
resolveInstanceMethod:
或resolveClassMethod:
来决定是否动态添加方法。如果动态添加,则消息得到处理,消息转发结束;否则,进入下一步。调用
forwardingTargetForSelector:
来确定能不能把这条消息转给其他接收者处理,如果返回一个非self
的对象,则会把消息发送给该对象,消息转发结束;否则,进入下一步。通过
methodSignatureForSelector:
方法获取签名,如果签名为nil,则消息无法处理,抛出异常;否则,调用forwardInvocation:
方法,调用成功则消息转发结束,调用失败则消息无法处理,抛出异常。
id GetterName(id self, SEL cmd) {
return objc_getAssociatedObject(self, cmd);
} void SetterName(id self, SEL cmd, NSString *value) {
NSString *sel = NSStringFromSelector(cmd);
NSString *key = [sel substringWithRange:NSMakeRange(, sel.length - )].lowercaseString;
objc_setAssociatedObject(self, NSSelectorFromString(key), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} if (sel == @selector(name)) {
// "@@:"的意思:
// 第一个字符表示函数的返回值类型,"@"表示GetterName函数的返回值类型为id
// 后面的字符表示函数的参数类型,"@:"表示GetterName函数接收两个参数,
// "@"表示参数类型为id,":"表示参数类型为SEL
class_addMethod(self, sel, (IMP)GetterName, "@@:");
return YES;
}
if (sel == @selector(setName:)) {
// "v@:@"的意思:
// "v"表示SetterName函数的返回值类型为void
// "@:@"参见上面
class_addMethod(self, sel, (IMP)SetterName, "v@:@");
return YES;
}
2.
给`NSNull`创建一个分类,并在.m中实现: #import "NSNull+safe.h"
@implementation NSNull (safe)
#define pLog
#define JsonObjects @[@"",@0,@{},@[]]
- (id)forwardingTargetForSelector:(SEL)aSelector {
for (id jsonObj in JsonObjects) {
if ([jsonObj respondsToSelector:aSelector]) {
#ifdef pLog
NSLog(@"NULL出现啦!这个对象应该是是_%@",[jsonObj class]);
#endif
return jsonObj;
}
}
return [super forwardingTargetForSelector:aSelector];
}
https://www.jianshu.com/p/c5bdd6f7a68c
第31月第17天 resolveInstanceMethod的更多相关文章
- ADO.NET数据访问基础与综合应用2020年10月31日20:17:09学习笔记
四.创建数据表 1.数据表的名称. 2.表中的字段名.数据类型.是否可以为空.字段的约束.必备的字段(通常会有一个ID,表示实体的唯一性:可以直接手写,也可以使用种子标识自动生成,给定起始值,给定增长 ...
- 第31月第25天 xcode debug 限制uitextfiled输入
1.xcode debug 了解了每个设置的意思,个人觉得对于一个普通的app来说可以这样配置这些设置: Generate Debug Symbols:DEBUG和RELEASE下均设为YES(和Xc ...
- 第31月第19天 NV12
1. //设置CIContext,并从CIImage -> CGImage -> UIImage CIContext *context = [CIContext contextWithOp ...
- 第31月第15天 -fembed-bitcode
1. 确保打包的时候使用的是fembed-bitcode, 而不是fembed-bitcode-maker fembed-bitcode-maker:只是简单的标记一下在archive出来的二进制中b ...
- 第31月第10天 tableview头部空白 Other Linker Flags rtmp
1.ios10 tableview头部空白 if (@available(iOS 11.0, *)) { self.tableView.contentInsetAdjustmentBehavior = ...
- 第31月 第9天 责任链AppDelegate
1.AppDelegate 到这里我们把解决方案再明确一下:把 AppDelegate 的调用解耦成一个 责任链 模型.并且满足以下特征: 每个模块都可以无限制的实现 AppDelegate 的方法. ...
- 第27月第17天 objc_msgSendSuper
1.objc_msgSendSuper super 的含义,消息转发会调用 objc_msgSendSuper, 就是 去父类的方法列表中找到 initWithFrame:这个方法,然后调用,调用的主 ...
- 第25月第17天 django rest framwork authentication /tmp/mysql.sock
1.authentication https://www.django-rest-framework.org/api-guide/authentication/#authentication 2.dj ...
- 第20月第17天 mvvm 多次点击push -ObjC
1. 响应式库EasyReact建成后,为了能使其得到更好的利用,更好地降低使用的理解和学习成本,臧成威老师又带领团队开发了基于响应式的MVVM框架:EasyMVVM. https://www.jia ...
随机推荐
- 基本服务器的AAA实验(Cisco PT)
1.实验拓扑 2.不通网段间的ping通测试 从pc-a ping到pc-b 从pc-a ping到pc-c 从pc-b ping到pc-c 3.配置过程 a.在路由器R1上配置一个本地用户账号并且利 ...
- MyBatis学习日记(三):戏说MyBatis配置文件
properties标签 properties标签可以用来加载别的配置文件,比如可以加载数据库的配置文件,jdbc.properties. 下面是jdbc.properties jdbc.driver ...
- 微信连wifi认证
官网 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444894086 https://blog.csdn.net/u0116 ...
- mysql5.7出现大量too many connections及too many open files错误,且配置最大连接数未生效
too many connections是由于mysql配置中连接数过少,不足以支撑当前的并发数,too many open files是由于mysql open_files_limit的值大小不够. ...
- JS 设计模式五 -- 命令模式
概念 命令模式中的命令(command) 指的是 一个执行某些待定事情的指令. 用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 例子 假设html结构如下: &l ...
- 移除 iview的Table组件固定两头后box-shadow阴影效果
.ivu-table-fixed{ box-shadow:0 0 0 #fff; }
- 【zabbix教程系列】三、zabbix 3.4 在centos 7 上安装详细步骤
一.环境准备 [root@ltt01 ~]# ip a : lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN qlen ...
- golang异常处理
一.使用defer+recover 错误例子: [root@localhostgo_test]#cat t1.go package main func main(){ panic(1) } [root ...
- IIS7.0 asp不能连接access数据 静态系统后台列表不显示 的问题
首先看一下系统磁盘的格式,看是NTFS的还是FAT32的,如果是NTFS的一般就是权限的问题,因为iis读取数据库在系统盘是有缓存的,所以对权限有要求,找到系统盘缓存目录: C:/Windows/te ...
- UOJ22 UR #1外星人(动态规划)
https://www.cnblogs.com/Gloid/p/10629779.html 这一场的D. #include<bits/stdc++.h> using namespace s ...