JavaScriptCore 外部数组

Posted

技术标签:

【中文标题】JavaScriptCore 外部数组【英文标题】:JavaScriptCore External Arrays 【发布时间】:2014-02-06 23:55:03 【问题描述】:

我一直在搞乱 iosjavascriptCore,我一直在尝试找出一种方法来按照 v8 中的“SetIndexedPropertiesToExternalArrayData”的方式做一些事情,我将在其中有一个 javascript 对象,并将其设置为数组数据指向另一个对象的数组。例如,如果我有一个空的 javascript 对象和另一个看起来像这样的 javascript 对象:

 '0': 0, '1': 1, '2': 2 ;

如果我要让空的 javascript 对象指向数组对象,那么每当我调用 [what used to be empty] 数组 [] 运算符时,它将与其他 javascript 的数组值相同。

我一直在尝试玩不同的东西,但我还没有找到方法。我的最终目标是在 iOS 中创建类型化数组,但如果我没记错的话,JavaScriptCore 的 iOS 构建中不存在外部数组和类型化数组?

非常感谢。

【问题讨论】:

【参考方案1】:

以下 IOS 代码显示了一个示例,该示例在 iOS 的 JavaScriptCore 中将键控数组从一个对象分配给另一个对象,然后在复制后对目标对象使用数组运算符。 我还展示了在 IOS Objective-C 和 JavaScriptCore 之间传递这些对象作为从 Objective-C 设置的离散 Javascript 对象以及将对象作为参数传递给 Javascript 函数。

JSContext *javascriptContext  = [[JSContext alloc] init];
javascriptContext[@"consoleLog"] = ^(NSString *message) 
    NSLog(@"Javascript log: %@",message);
;

NSDictionary *myArray = [NSDictionary dictionaryWithObjectsAndKeys:@0, @"item0", @1, @"item1", @2, @"item2", nil];
NSLog(@"myArray = %@", myArray);
javascriptContext[@"obj1"] = myArray;
[javascriptContext evaluateScript:@"var myFunction = function(arrayArg) 
    consoleLog(\"obj1['item2'] = \" + obj1['item2']);
    consoleLog(\"arrayArg['item0'] = \" + arrayArg['item0']);
    var obj2 = obj1;
    consoleLog(\"obj2['item1'] = \" + obj2['item1']);
    obj1 =  'key0': 0, 'key1': 1, 'key2': 2 ;
    obj2 = obj1;
    consoleLog(\"obj2['key0'] = \" + obj2['key0']);
    return obj2;
;"];
JSValue *function = javascriptContext[@"myFunction"];
NSArray *argList = [NSArray arrayWithObjects:myArray, nil];
JSValue *result = [function callWithArguments:argList];
NSDictionary *javascriptArray = [result toObject];
NSLog(@"javascriptArray returned = %@", javascriptArray);

如果您要复制此代码,请删除包含 javascript 函数的字符串中嵌入的换行符(为了清楚起见,我添加了这些)。

此代码生成以下控制台日志:

2014-02-07 16:49:55.901 TestHarness[4674:70b] myArray = 
    item0 = 0;
    item1 = 1;
    item2 = 2;

2014-02-07 16:49:55.903 TestHarness[4674:70b] Javascript log: obj1['item2'] = 2
2014-02-07 16:49:55.904 TestHarness[4674:70b] Javascript log: arrayArg['item0'] = 0
2014-02-07 16:49:55.904 TestHarness[4674:70b] Javascript log: obj2['item1'] = 1
2014-02-07 16:49:55.904 TestHarness[4674:70b] Javascript log: obj2['key0'] = 0
2014-02-07 16:49:55.905 TestHarness[4674:70b] javascriptArray returned = 
    key0 = 0;
    key1 = 1;
    key2 = 2;

从示例代码中可以看出,IOS JavaScriptCore 框架提供了 NSDictionary 对象和 Javascript 数组之间的内置转换。查看 JSValue.h,它将这种内置转换描述为:NSDictionary 转换为 JavaScript“对象”,但数组运算符在从 Objective-C 注入的值上工作正常,并且返回的对象为新的Javascript 键控数组是 Objective-C 中有效的 NSDictionary 对象

这能解决您的问题还是我误解了?

【讨论】:

在将数组分配给 JavaScript 对象后更改 Objective-C 外部数组中的一个元素的进一步实验表明 JavaScriptCore 获取数组内容的副本而不是指向外部数组(它不会'看不到变化)。我不认为我的回答能解决你的问题。 是的,虽然我很感谢您的帮助,但不幸的是,这并不能解决问题。你是对的,它确实在objective-c中复制了数组,就JavaScriptCore而言,试图让一个javascript对象的数组指向另一个似乎是不可能的。我仍在尝试找出一种方法来做到这一点,但到目前为止还没有运气。 我还想指出,我只是想仅对索引数组执行此操作。我有几个 javascript 类也包含其他对象,比如“函数”和对象需要的其他数据,所以试图只让索引部分指向另一个数组似乎相当困难。【参考方案2】:

iOS 7 附带的 JavaScriptCore 构建确实具有类型数组,但不幸的是,公共 API 没有公开它们,因此您无法从原生访问它们的数据。但是,there's this iOS-specific fork of JavaScriptCore 公开了一个围绕类型化数组 API 的公共包装器。

【讨论】:

以上是关于JavaScriptCore 外部数组的主要内容,如果未能解决你的问题,请参考以下文章

JavaScriptCore学习之JavaScriptCore

在 JavaScriptCore 中获取默认导出

iOS js oc相互调用(JavaScriptCore)

Swift Playgrounds 中的 JavaScriptCore

iOS9 上的 JavaScriptCore 崩溃

转载 iOS js oc相互调用(JavaScriptCore)