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

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

{ '0': 0, '1': 1, '2': 2 };

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

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

非常感谢。

【问题讨论】:

    标签: javascriptcore


    【解决方案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 的公共包装器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多