博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JSPatch常见问题解答
阅读量:5091 次
发布时间:2019-06-13

本文共 4202 字,大约阅读时间需要 14 分钟。

原文地址:https://github.com/bang590/JSPatch/wiki/JSPatch%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94

一、block使用规则

1、在 JSPatch 若要向 Objective-C 传递 block,需要使用 block(paramTypes, function) 函数封装:,封装后的值已经不是 JS 函数,不能直接在 JS 上调用:

var blk = block("BOOL", function(b){ }) blk(1) //crash

若想在 JS 上调用,请调用封装前的函数:

var func = function(b){};var blk = block("BOOL", func) func(1) //it's OK

2、不允许在 JS 的 block 中传入含有 undefined 的数组或对象。比如传入 ["JSPatch", undefined] 的数组或 {obj: undefined} 的对象,这种语法在 JavaScript 中没有错误,但是在 Objective-C 中是不允许的。

3、如果 block 的参数里含有 block,paramTypes 需要写成 NSBlock *

var blk = block("BOOL, NSBlock *", function(b, blk){ if (b) { blk(true) } })

4、在 Objective-C 中传入到 JSPatch 中的 Block 会转换为 function,如果需要再将该 Block 传回到 OC,依旧需要用 block(paramTypes, function) 封装。

//Objective-C代码- (void)excuteBlock:(JSBlock)block {    if (block) {        block(@"Hello, JSPatch"); } } - (JSBlock)returnBlock { JSBlock block = ^(NSString *str) { NSLog(@"%@", str); }; return block; }
//JSPatch脚本var blk = self.returnBlock()self.excuteBlock(block("NSString *", blk))

5、暂时不支持向OC端传递含有浮点型参数的block,比如如下的情况:

//Objective-C代码typedef void (^JSBlock)(CGFloat fl);- (void)doBlock:(JSBlock)blk {    if (blk) { blk(123.456f); } }
//JSPatch脚本self.doBlock(block("CGFloat",function(fl){ console.log(fl) //得到的结果不会是你想要的结果 } ))

6、在block中使用到self时,需要在使用block之前先将self赋值给另外一个变量,然后在block中使用这个变量。如:

//JSPatch脚本var slf = selfself.requestWithCompletion(block("BOOL, NSError*", function(success, error){ slf.label().setText("complete") }) )

二、在 JSPatch 中表示 nil 和 [NSNull null] 及使用其他特殊类型

1、在 JSPatch 中使用 null 或 undefined 来表示 Objective-C 的 nil, 使用 nsnull 表示[NSNull null]

2、在 JSPatch 中判断 Objective-C对象是否为空时,使用 if(!obj){} 的形式而不能使用 if(obj == null){} 或 if(obj == undefined){}

3、在 JSPatch 中使用 struct、selector 的用法可参考

三、调用包含id *类型参数的方法

详见 

四、在 JSPatch 使用父类方法

使用 self.super() 调用父类方法

defineClass("JPTableViewController", {  viewDidLoad: function() { self.super().viewDidLoad(); } })

五、调用多参数的方法

JSPatch 中使用 _ 来替代Objective-C中的 :, 多以调用多参数的 Objective-C 方法需要像下面这样。

var error = require('NSError').errorWithDomain_code_userInfo("UnKnown_Error", -1, null)

如果调用的方法含有一个下划线,就需要使用双下划线来表示。例如:

- (void)p_privateMethod;

JSPatch中可以这样调用

self.p__privateMethod()

不支持方法中含有双(或更多)下划线的方法,如 - (void)p__privateMethod;。 但是如果是要获取含有双(或更多)下划线的property(这种情况比带有双下划线的方法更为常见一些),可以使用 KVC 的 valueForKey 方法。例如:

@property (nonatomic, string) id __privateObject;

JSPatch中可以这样获取

var obj = self.valueForKey("__privateObject")

六、JSPatch 中的 NSArray,NSString,NSDictionary

在 JSPatch 中不能将 Objective-C 中的 NSArrayNSStringNSDictionary 与 JavaScript 的ArrayStringObject 进行混用。

//Objective-C- (NSArray *)returnNSArray {    return @[@"Objective-C", @"Swift"]; }
var nsarray = self.returnNSArray()var array = ["Objective-C", "Swift"] //这两者不能混用,因为他们是不同的类型。 var wrongStr = nsarray[0] //得到的是一个不正确的对象,请不要使用取下标的方式获取NSArray/NSDictionar对象。 var rightStr = nsarray.toJS()[0] //先unbox返回的对象,然后取出其中的数据 或 var rightStr = nsarray.objectAtIndex(0) //使用Objective-C方法获取NSArray/NSDictionary中的对象

具体可参考

七、常量与宏

Objective-C 里的常量不能直接在 JS 上使用,可以直接在 JS 上用具体值代替,或者在 JS 上重新定义同名的全局变量:

//jsvar UIRectEdgeNone   = 0,    UIRectEdgeTop    = 1 << 0, UIRectEdgeLeft = 1 << 1, UIRectEdgeBottom = 1 << 2, UIRectEdgeRight = 1 << 3

Objective-C 里的宏同样不能直接在 JS 上使用,若定义的宏是一个值,可以在 JS 定义同样的全局变量代替,若定义的宏是程序,或者在底层才能获取到的值,例如 CGFLOAT_MIN,可以通过添加扩展的方式提供支持:

@implementation JPMacroSupport+ (void)main:(JSContext *)context { context[@"CGFLOAT_MIN"] = ^CGFloat() { return CGFLOAT_MIN; } } @end
require('JPEngine').addExtensions(['JPMacroSupport']) var floatMin = CGFLOAT_MIN();

八、Property / 私有变量的获取和赋值

详见 

九、类全局变量

目前在类里定义的 static 全局变量无法在 JS 上获取到,若要在 JS 拿到这个变量,需要在 OC 有类方法或实例方法它返回:

static NSString *name;@implementation JPTestObject+ (NSString *)name { return name; } @end
var name = JPTestObject.name() //拿到全局变量值

十、Swift

使用 defineClass() 覆盖 Swift 类时,类名应为 项目名.原类名,例如项目 demo 里用 Swift 定义了 ViewController 类,在 JS 覆盖这个类方法时要这样写:

defineClass('demo.ViewController', {})

十一、可变参数

JSPatch 不支持带可变参数方法的调用,例如:

//OC: [NSString stringWithFormat:@"%d %@", i, obj];NSString.stringWithFormat("%d %@", i, obj); //not working

因为 JSPatch 原理是通过 NSInvocation 动态调用方法,而 NSInvocation 不支持可变参数,参见。

十二、其他问题

不可以使用 require('NSNumber').alloc(),原因见

 

转载于:https://www.cnblogs.com/yuliblossom/p/5094655.html

你可能感兴趣的文章
cer证书签名验证
查看>>
synchronized
查看>>
【深度学习】caffe 中的一些参数介绍
查看>>
Python-Web框架的本质
查看>>
QML学习笔记之一
查看>>
App右上角数字
查看>>
从.NET中委托写法的演变谈开去(上):委托与匿名方法
查看>>
小算法
查看>>
201521123024 《java程序设计》 第12周学习总结
查看>>
新作《ASP.NET MVC 5框架揭秘》正式出版
查看>>
IdentityServer4-用EF配置Client(一)
查看>>
WPF中实现多选ComboBox控件
查看>>
读构建之法第四章第十七章有感
查看>>
Windows Phone开发(4):框架和页 转:http://blog.csdn.net/tcjiaan/article/details/7263146
查看>>
Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)【转】
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>
IOS-图片操作集合
查看>>
IO—》Properties类&序列化流与反序列化流
查看>>