JavaScriptCore External Arrays

点点圈 提交于 2020-01-04 11:02:15

问题


I've been messing around with JavaScriptCore for iOS and I've been trying to figure out a way to do something along the lines of "SetIndexedPropertiesToExternalArrayData" from v8, where I would have a javascript object, and set it's array data to point to another object's array. For example, if I were to have an empty javascript object, and another javascript object that looked like:

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

and if I were to make the empty javascript object point to the array object, whenever I call the [what used to be empty] array [] operator it would be the same as the other javascript's array values.

I've been trying to play around with different things and I have yet to find a way to do so. My end goal of this is to create typed arrays in iOS, but if I'm not mistaken, external arrays and typed arrays are non existent in the iOS build of JavaScriptCore?

Thanks a lot in advance.


回答1:


The following IOS code shows an example of assigning keyed arrays from one object to another inside JavaScriptCore for iOS then using the array operator on the target object after the copy. I've also shown passing these objects between IOS Objective-C and JavaScriptCore both as discrete Javascript objects set from Objective-C as well as passing the object as a parameter to a Javascript function.

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);

If you are going to copy this code, please remove the embedded newlines in the string containing the javascript function (I added these for clarity).

This code produces the following console log:

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;
}

As you can see from the sample code, the IOS JavaScriptCore framework is providing built-in conversion between the NSDictionary object and Javascript arrays. Looking at JSValue.h it describes this built-in conversion as: NSDictionary converts to a JavaScript "object" but the array operator is working fine on values injected from Objective-C and the object returned for a new Javascript keyed array is valid NSDictionary object in Objective-C

Does this solve your question or have I misunderstood?




回答2:


The build of JavaScriptCore that comes with iOS 7 does have typed arrays, but unfortunately the public API doesn't expose them so you can't touch their data from native. However, there's this iOS-specific fork of JavaScriptCore that exposes a public wrapper around the typed arrays API.



来源:https://stackoverflow.com/questions/21616641/javascriptcore-external-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!