JSPatch常见问题解答

原文地址: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(),原因见这里

时间: 2024-08-17 21:40:51

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

下载中心常见问题解答【Q&A帮助】

公告 1.下载中心不支持迅雷以及各个浏览器(如360.猎豹等)自带的加速模块下载,如果您正在使用,请关闭后再下载. 2. 本文内容较多,可利用"Ctrl+F"进行搜寻,如果没有找到您想知道的问题,请留言提出,我们会及时答复您.如果您的问题具有代表性,将会采纳入正文中.本文中已做出解答的问题,请不要重复提问. 下载常见问题 1.Q:为什么下载的资料提示解压错误?而且只有7KB? A:如果无法打开附件并提示解压报错,可以已下载的附件大小和资料原本标注的大小是否一致,如果资料下载完只有7KB

U盘启动盘常见问题解答

主要为大家详细说明U当家U盘装系统,U盘启动盘制作常见问题解答,希望对你有所帮助. 1.U盘启动盘制作工具是什么? U盘启动盘制作工具是将U盘变成为带有winpe系统的启动盘.方便用户维护和安装系统!(例如:系统不能启动时,我们使用已经制作好的U当家U盘启动盘就可以将C盘的重要文件复制出来,还可以保证数据的完整性.) 2.为什么我用U盘装系统工具制作好的U盘里面是空的? U盘装系统工具采用的是隐藏分区技术,看不到里面的内容是正常现象,你可以对比制作前的U盘容量,看容量是否少了 400兆,如果是就

佳能视频恢复--佳能MOV视频恢复软件常见问题解答

佳能视频恢复--MOV视频恢复软件常见问题解答 佳能相机的使用可以说现在很常见,而其出产的MOV视频被广泛应用到各个领域.而对于现在这个存在各种数据安全问题的时代,mov视频的丢失是极其常见的.那么如何找回丢失的mov视频呢? 来自江苏的顾先生是一名视频编辑者,前段时间接到一个客户要求,将他们拍摄的一段mov广告视频加工制作一下.在制作好之后准备交给客户时,却由于操作失误,导致该视频丢失了.现在重新制作时间已经赶不及了,因此只能想方法还原之前的视频.后来顾先生通过朋友介绍,使用了甲驭科技自主研发

sencha touch 常见问题解答

欢迎留言补充 1.sencha touch 是什么? 答:Sencha touch框架是世界上第一个基于HTML 5的移动应用框架.它可以让你的Web应用看起来像网络应用.美丽的用户界面组件和丰富的数据管理,全部基于最新的HTML 5和CSS3的 WEB标准,全面兼容Android和iOS设备. 2.sencha touch 能够访问原生的设备功能,如摄像头.麦克风吗? 答:Sencha touch只是一个HTML 5框架,所以想要它能够访问原生的设备功能,需要浏览器提供支持才可以. 如果需要访

淘宝卖家缺货退款的常见问题解答

今天小编为大家带来的是"淘宝卖家缺货退款的常见问题解答".很多朋友都碰见过淘宝卖家缺货退款的问题,但是都不知道怎么解决,遇到有关淘宝卖家缺货退款的问题后我们该怎么办呢?很多买家都不知道淘宝卖家缺货怎么赔偿.今天就跟随小编一起看看,淘宝卖家缺货怎么办. 一.卖家缺货 交易状态为"买家已付款,等待卖家发货",但卖家以缺货,无货等理由,未按约定时间发货; 1. 当买家以"卖家缺货"原因申请退款时,您会看到: "当前退款状态:退款协议等待卖家确

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

前几天刚刚注册了博客园,我想写一些技巧性的教程,今天给大家分享一个MySQL同步常见问题解答. Q:如果主服务器正在运行并且不想停止主服务器,怎样配置一个从服务器? A:有多种方法.如果你在某时间点做过主服务器备份并且记录了相应快照的二进制日志名和偏移量(通过SHOW MASTER STATUS命令的输出),采用下面的步骤: 1.确保从服务器分配了一个唯一的服务器ID号. 2.在从服务器上执行下面的语句,为每个选项填入适当的值:mysql> CHANGE MASTER TO -> MASTER

dubbo常见问题解答FAQ

常见问题解答 1. 如果服务注册不上怎么办? 2. 出现RpcException: No provider available for remote service异常怎么办? 3. 出现调用超时com.alibaba.dubbo.remoting.TimeoutException异常怎么办? 4. 出现hessian序列化失败com.caucho.hessian.client.HessianRuntimeException怎么办?< /h3> 5. 出现Configuration probl

ecshop模板开发制作教程及常见问题解答

ecshop模板开发制作教程 下列章节的适用于ECshop程序. 同时这里许多内容和一些 Smarty相关. 假如您已经熟悉这些内容可跳过不阅读.假如您是ECshop新手并且想diy一下自己的店铺, 那您应该认真详细地从头到尾读一遍这些章节.( ps: 大家不要紧张,我会尽量用人类的语言和大家交流,实在万不得已才会用机器语言展示给大家 ) 希望大家能够通过本教程,想要什么模板都能自己做出来.哈哈!一起加油吧! 第一章节: 读取这些内容,您将了解: 每个前台页面所对应的模板页面,模板文件的目录结构

英特尔&#174; 实感? SDK 前置摄像头 (F200) 常见问题解答

原文地址 https://software.intel.com/zh-cn/articles/intel-realsense-sdk-faq-for-front-facing-camera-f200?utm_source=cnblog&utm_medium=Social+Media&utm_campaign=Realsende_PRC_Q415_Syndication 该常见问题解答提供了英特尔® 实感™ SDK 黄金版 R1 和 R2 的硬件要求和特性信息. 要求 使用英特尔® 实感™