原文地址: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) 函数封装:Block的详细使用方法,封装后的值已经不是 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 = self
self.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 *类型参数的方法

详见 基础用法 - 传递 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 上重新定义同名的全局变量:

//js
var 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 / 私有变量的获取和赋值

详见 defineClass使用文档

九、类全局变量

目前在类里定义的 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(),原因见这里

JSPatch常见问题解答的更多相关文章

  1. MySQL同步常见问题解答(自己的小心得)

    前几天刚刚注册了博客园,我想写一些技巧性的教程,今天给大家分享一个MySQL同步常见问题解答. Q:如果主服务器正在运行并且不想停止主服务器,怎样配置一个从服务器? A:有多种方法.如果你在某时间点做 ...

  2. Delphi XE5 常见问题解答

    Delphi XE5 常见问题解答 有关于新即时试用的问题吗?请看看 RAD Studio 即时试用常见问答. 常见问题 什么是 Delphi? Embarcadero? Delphi? XE5 是易 ...

  3. SSL/TLS 高强度加密: 常见问题解答

    关于这个模块 mod_ssl 简史 mod_ssl会受到Wassenaar Arrangement(瓦森纳协议)的影响吗? mod_ssl 简史 mod_ssl v1 最早在1998年4月由Ralf ...

  4. [!!!!!]Inno Setup教程-常见问题解答

    [转]Inno Setup教程-常见问题解答 功能 * 翻译 Inno Setup 文字  * 它支持 MBCS (多字节字符集) 吗?  * 将来会支持 Windows Installer 吗?   ...

  5. 英特尔® 实感™ SDK 前置摄像头 (F200) 常见问题解答

    原文地址 https://software.intel.com/zh-cn/articles/intel-realsense-sdk-faq-for-front-facing-camera-f200? ...

  6. 我个人有关 Azure 网络 SLA、带宽、延迟、性能、SLB、DNS、DMZ、VNET、IPv6 等的 Azure 常见问题解答

    Igor Pagliai(微软)   2014 年 9月 28日上午 5:57  年 11 月 3 年欧洲 TechEd 大会新宣布的内容). 重要提示:这篇文章中我提供的信息具有时间敏感性,因为这些 ...

  7. 关于CopyU!的常见问题解答

    拷优(CopyU!)常见问题解答 本常见问题解答列举了一些常见的疑问及其解释,如果您对CopyU!有任何问题,请您首先查看本解答! 本解答将会保持随时更新! 一.使用篇:     1.问:我的杀毒软件 ...

  8. genymotion常见问题解答

    [转]常见问题解答 很多人喜欢使用Genymotion这款安卓模拟器,但是虽然Genymotion很好用,可是却有各种问题存在哦,下面潇潇就一些常见的Genymotion问题来说下解决方法吧. 为什么 ...

  9. Linux的常见问题解答和管理技巧

    Linux的常见问题解答和管理技巧 一. 如何建立多用户 提醒大家一句,别一直使用root用户,因为root用户在系统中有着至高无上的权力,一不小心就可能破坏系统.比如我们想删除/temp目录下的文件 ...

随机推荐

  1. 一些pc端web事件移动端不再可行

    1.onkeyUp,onkeyDown,onkeyPress等事件不再管用,要用oninput代替   2.onclick事件会有延迟,因为手机需要等待判断是否是双击事件(ondblclick).所以 ...

  2. 使用JavaScript的history对象来实现页面前进后退(go/back/forward)。

    我们都知道JavaScript有history对象,主要是用来记录浏览器窗口的浏览记录.但是,JS脚本是不允许访问到这个记录里面的内容(隐私). 常见的用法是: history.back();//返回 ...

  3. 柏克EPS应急电源签约联达大厦保安全

    近日,柏克EPS应急电源成功签约佛山市联达大厦,保障大厦电力安全. 佛山市联达大厦占地6674㎡,总建筑面积约4.6万㎡,设有两层地下室,提供201个停车位,地面29层.大厦大楼分为主楼和副楼,主楼地 ...

  4. 想学好web前端,需要看哪些书籍

    目前市场上HTML.CSS 类别书籍,都是大同小异,在当当网.卓越网搜索一下很多推荐.今天web前端大牛根据自己的经验总结如下:Javascript 的书籍推荐看老外写的,国内很多 Javascrip ...

  5. Highcharts指南

    摘要 Highcharts图表控件是目前使用最为广泛的图表控件.本文将从零开始逐步为你介绍Highcharts图表控件.通过本文,你将学会如何配置Highcharts以及动态生成Highchart图表 ...

  6. C#中Invoke的用法(转)

    在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界 ...

  7. Flask + WSGI + Nginx 云部署

    这几天学着用flask写一些rest api,然后部署到云上.这个过程虽然网上有很多的教程,但还是遇到不少的问题! 采用flask的原因是因为它比较容易上手吧.用flask有专门restful api ...

  8. 解决Oracle+weblogic系统死机的问题

    前段时间发布的系统(Oracle+weblogic)频繁挂掉,每天早上9点.下午2点高峰期就挂,纠结了很长时间,最终解决,方法描述下. 执行select count(*),status from v$ ...

  9. 深入理解JavaScript系列:JavaScript的构成

    此篇文章不是干货类型,也算不上概念阐述,就是简单的进行一个思路上的整理. 要了解一样东西或者完成一件事情,首要的就是先要搞清楚他是什么.作为一个前端开发人员,JavaScript应该算作是最核心之一的 ...

  10. VIm 一些常用的设置

    一些常用的vim设置   以下内容皆来源于网络,感谢原作者.如果引用出处错误,请告知以便修改. 1. vim的几种模式和按键映射 转载自:[1] Map是Vim强大的一个重要原因,可以自定义各种快捷键 ...