defineProtocol 使用文档
2016-03-03 11:50
555 查看
问题
JSPatch 为一个类新增原本 OC 不存在的方法时,所有的参数类型都会定义为 id类型,因为这种在 JS 里新增的方法一般不会在 OC 上调用,而是在 JS 上用,JS 可以认为一切变量都是对象,没有类型之分,所以全部定义为
id类型。
但有种场景,需要让新增的方法参数类型不是
id,那就是,在 OC 里
.h文件定义了一个方法,这个方法里的参数和返回值不都是
id类型,但是在
.m文件中由于疏忽没有实现这个方法,导致其他地方调用这个方法时找不到这个方法造成
crash,要用 JSPatch 修复这样的 bug,就需要 JSPatch 可以动态添加指定参数类型的方法。对此可以用
defineProtocol()接口定义参数类型,再在
defineClass()中实现,就可以动态添加指定参数类型的方法了。
API
defineProtocol(protocolDeclaration, instanceMethods , classMethods)
@param
protocolDeclaration:字符串,新增protocol的名字
@param
instanceMethods:字典,要添加到protocol的实例方法
@param
classMethods:字典,要添加到protocol的类方法
需要说明的是,在runtime中,协议一旦注册后就不可再修改,所以只能新增协议
在defineProtocol中
protocolDeclaration参数输入协议名称
在defineProtocol中
instanceMethods参数输入协议内实例方法的字典,以方法名为Key,Value也是一个字典,是实例方法的信息
在defineProtocol中
classMethods参数输入协议内类方法的字典,以方法名为Key,Value也是一个字典,是类方法的信息
示例
例如在 JPTestObject 对象中,.h头文件定义了这样一个接口:
@interface JPTestObject - (NSString *)stringWithRect:(CGRect)rect withNum:(float)num withArray:(NSArray *)arr; @end
但在
.m文件中没有实现这个接口,导致其他地方调用这个方法时 crash。对此可以用 JSPatch 修复,分两个步骤:
把这个方法定义成一个 protocol
defineClass中实现这个 protocol
先看第一步,用
defineProtocol接口把这个方法定义在一个新的 protocol 中:
defineProtocol('JPDemoProtocol',{ stringWithRect_withNum_withArray: { paramsType:"CGRect, float, NSArray*", returnType:"id", }, }
接着第二步,在 defineClass 中实现这个方法:
defineClass('JPTestObject : NSObject <JPDemoProtocol>', { stringWithRect_withNum_withArray:function(rect, num, arr){ //use rect/num/arr params here return @"success"; }, }
大功告成,新增的方法参数类型会遵循 defineProtocol 里定义的类型,这时 OC 中再调用这个方法时就会调到在 JSPatch 新增的方法,让 APP 避免 crash。
更多使用 Case 参见 demo 工程里的
newProtocolTest.js
更多参数类型
1.paramsType和
returnType中可以直接使用的参数类型位包括
id,
BOOL,
int,
void,
char,
short,
unsigned short,
unsigned int,
long,
unsigned long,
long long,
float,
double,
CGFloat,
CGSize,
CGRect,
CGPoint,
CGSize,
CGVector,
UIEdgeInset,
NSInteger,
SEL,
block。
2.参数是 OC 对象
NSObject,比如
NSArray,
CustomObject,可以写作
id,也可以直接写类名,效果一样
paramsType:"id" paramsType:"CustomObject"
3.对于无法支持的参数,比如其他结构体,
customStruct,可以使用
typeEncode可选字段
testProtocolConstumStruct:{ paramsType:"unknown", returnType:"int", typeEncode:"i@:{CGVector=dd}" },
4.当使用
typeEncode时,类型字符串可以不必匹配任意填写,比如填写unknown,比如填写xxx,但是要求
paramsType的个数必须保证准确
5.自行填写的
typeEncode,可以通过在项目中使用OC代码,在运行时通过系统获取
SEL selstr = NSSelectorFromString(@"testProtocolConstumStruct:"); Method method = class_getInstanceMethod(class, selstr); const char* type = method_getTypeEncoding(logmanagermethod);
相关文章推荐
- 第4章 让人畅所欲言的心理策略
- 【vijos】P1911 珠心算测验
- 去除多余cell的线
- sqlserver 自定义、删除、执行 函数和存储过程
- Effective C++读书笔记 条款03:尽可能使用const
- cocos3.9 【 protoc-gen-lua 配置 】
- PIC C语言编程_PICC中变量修饰关键词
- c 字符串函数
- mysql数据库设置默认字符集
- umeng第三方登陆授权 getPlatformInfo 无法获取 access_token
- 第三方分享的部分准备知识
- [Android 性能优化系列]布局篇之通过<include>复用布局
- URL中带加号的处理
- JMS两种模型,布上apache-activemq服务器JMS(四)
- IOS中的几种比较常见的延时方法的介绍及各自优缺点
- Android gradle配置
- linux sed指令的替换操作
- 前端知识体系
- equals方法避免空指针的比较方法
- 闭包 转