Introduction to iOS7 new JavaScriptCore framework

Source: Internet
Author: User
Tags javascript array

This framework is only a package of JavaScriptCore implemented in C/C ++ in webkit. In iOS development of the old version, many developers will introduce the webkit Library to the Project for compilation and usage. However, although iOS7 regards it as a standard library, I have not found official documents like that in Apple Developer to introduce the specific usage of this framework.

Classes in JavaScriptCore

After JavaScriptCore is introduced in the project, it is linked to the header file. In addition to the Copyright comment of the large segment, we can see that as long as five files are introduced, each file defines the class corresponding to the file name:

  • JSContext
  • JSValue
  • JSManagedValue
  • JSVirtualMachine
  • JSExport

    Although the comments in the Code are also described in detail, the code is more convincing for programmers, for example, the same figure is the top ten thousand words. This article first describes the JSContext and JSValue which are relatively easy to understand but commonly used, as well as the usage and effects of these methods.

    JSContext and JSValue

    JSVirtualMachineProvides underlying resources for JavaScript operations,JSContextIt provides a runtime environment for it.- (JSValue *)evaluateScript:(NSString *)script;Method to execute a JavaScript script, and if there are methods, variables and other information in it will be stored for use as needed. JSContext is created based onJSVirtualMachine:- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;.- (id)init;Then, a newJSVirtualMachineObject and then call the initialization method of the front.

    JSValueIt can be said that it is a bridge between JavaScript and Object-C. It provides a variety of methods to easily convert JavaScript data types into Objective-C, or convert the past. The following table shows the one-to-one matching method:

    Objective-C JavaScript JSValue Convert JSValue Constructor
    Nil Undefined ValueWithUndefinedInContext
    NSNull Null ValueWithNullInContext:
    NSString String ToString
    NSNumber Number, boolean ToNumber
    ToBool
    ToDouble
    ToInt32
    ToUInt32
    ValueWithBool: inContext:
    ValueWithDouble: inContext:
    ValueWithInt32: inContext:
    ValueWithUInt32: inContext:
    NSDictionary Object ToDictionary ValueWithNewObjectInContext:
    NSArray Array object ToArray ValueWithNewArrayInContext:
    NSDate Date object ToDate
    NSBlock Function object
    Id Wrapper object ToObject
    ToObjectOfClass:
    ValueWithObject: inContext:
    Class Constructor object

    Basic type conversion

    Let's take a look at a simple example:

    1     JSContext *context = [[JSContext alloc] init];2     JSValue *jsVal = [context evaluateScript:@"21+7"];3     int iVal = [jsVal toInt32];4     NSLog(@"JSValue: %@, int: %d", jsVal, iVal);5      6     //Output:7     // JSValue: 28, int: 28

    You can also save a JavaScript variable inJSContextAnd obtain it by subscript. ForArrayOrObjectType,JSValueYou can also directly set values and assign values by subscript.

     1     JSContext *context = [[JSContext alloc] init]; 2     [context evaluateScript:@"var arr = [21, 7 , 'iderzheng.com'];"]; 3     JSValue *jsArr = context[@"arr"]; // Get array from JSContext 4       5     NSLog(@"JS Array: %@; Length: %@", jsArr, jsArr[@"length"]); 6     jsArr[1] = @"blog"; // Use JSValue as array 7     jsArr[7] = @7; 8       9     NSLog(@"JS Array: %@; Length: %d", jsArr, [jsArr[@"length"] toInt32]);10      11     NSArray *nsArr = [jsArr toArray];12     NSLog(@"NSArray: %@", nsArr);13      14     //Output:15     // JS Array: 21,7,iderzheng.com Length: 316     // JS Array: 21,blog,iderzheng.com,,,,,7 Length: 817     // NSArray: (18     // 21,19     // blog,20     // "iderzheng.com",21     // "
       
        ",22     // "
        
         ",23     // "
         
          ",24     // "
          
           ",25     // 726     // )
          
         
        
       

    The output results show that the Code successfully assigns data from Objective-C to the JavaScript array, andJSValueIt follows the array feature of JavaScript: the array size is automatically extended without subscript offside. And passJSValueYou can also obtain attributes on JavaScript objects. For example"length"The length of the JavaScript array is obtained. ConvertNSArrayAll the information is correctly converted.

    Method Conversion

    Various data types can be converted. The Objective-C Block can also be passed into JSContext for use as JavaScript. For examplelogMethod. Although JavaScritpCore does not come with it (after all, it does not run on a webpage, but naturally does not have windows, document, and console classes), you can define a Block method to call NSLog for simulation:

     1     JSContext *context = [[JSContext alloc] init]; 2     context[@"log"] = ^() { 3     NSLog(@"+++++++Begin Log+++++++"); 4       5     NSArray *args = [JSContext currentArguments]; 6     for (JSValue *jsVal in args) { 7     NSLog(@"%@", jsVal); 8     } 9      10     JSValue *this = [JSContext currentThis];11     NSLog(@"this: %@",this);12     NSLog(@"-------End Log-------");13     };14      15     [context evaluateScript:@"log('ider', [7, 21], { hello:'world', js:100 });"];16      17     //Output:18     // +++++++Begin Log+++++++19     // ider20     // 7,2121     // [object Object]22     // this: [object GlobalObject]23     // -------End Log-------

    If a Block is successfully called in JavaScript, the method returns to Objective-C, and still follows various features of the JavaScript method. For example, the method parameters are not fixed. Because of this,JSContextProvides a class method to obtain the parameter list (+ (JSContext *)currentContext;) And the object currently calling this method (+ (JSValue *)currentThis). For"this", The output content isGlobalObject, This is alsoJSContextObject Method- (JSValue *)globalObject;Returned content. Because we know that in JavaScript, all global variables and methods are actually a global variable attribute. In the browser, window is used, and what is JavaScriptCore is unknown.

    Block can be passed inJSContextMethod,JSValueNotoBlockTo Block the JavaScript method in Objetive-C. After all, the number and type of Block parameters are fixed. Although the method cannot be extractedJSValueProvided- (JSValue *)callWithArguments:(NSArray *)arguments;The method can in turn pass the parameter in to call the method.

     1     JSContext *context = [[JSContext alloc] init]; 2     [context evaluateScript:@"function add(a, b) { return a + b; }"]; 3     JSValue *add = context[@"add"]; 4     NSLog(@"Func: %@", add); 5       6     JSValue *sum = [add callWithArguments:@[@(7), @(21)]]; 7     NSLog(@"Sum: %d",[sum toInt32]); 8     //OutPut: 9     // Func: function add(a, b) { return a + b; }10     // Sum: 28

    JSValueAlso provides- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;This allows us to directly and simply call methods on objects. If the defined method is a global function, it should beJSContextOfglobalObjectThis method is called on an object. If it is a method on a JavaScript object, the correspondingJSValueObject call.

    Exception Handling

    Objective-C exceptions will be caught by Xcode at runtime, whileJSContextIf an exception occurs in the JavaScript executed inJSContextCaptured and stored inexceptionAttribute instead of being thrown out. Always checkJSContextObjectexceptionIs it notnilObviously it is not suitable. A more reasonable way isJSContextObject settingsexceptionHandlerWhich accepts^(JSContext *context, JSValue *exceptionValue)Block. The default value isexceptionValueAssigned to the passedcontextOfexceptionAttribute:

    1     ^(JSContext *context, JSValue *exceptionValue) {2         context.exception = exceptionValue;3     };

    We can alsoexceptionHandlerAssign a new Block so that we can immediately know when an exception occurs in JavaScript running:

     1     JSContext *context = [[JSContext alloc] init]; 2     context.exceptionHandler = ^(JSContext *con, JSValue *exception) { 3         NSLog(@"%@", exception); 4         con.exception = exception; 5     }; 6       7     [context evaluateScript:@"ider.zheng = 21"]; 8       9     //Output:10     // ReferenceError: Can't find variable: ider

    Block usage considerations

    From the previous examples and introductions, we should have realized the powerful role of Block in JavaScriptCore. It builds more bridges between JavaScript and Objective-C, making intercommunication more convenient. However, it should be noted that the Block is passedJSContextObject to convert it into a JavaScript method, or assign itexceptionHandlerAttribute,Do not directly use the externally definedJSContextObject orJSValue, It should be passed into the Block as a parameter, or throughJSContextClass Method+ (JSContext *)currentContext;. Otherwise, the memory cannot be properly released due to loop reference.

    For example, the preceding custom exception handling method is assigned to the inputJSContextObjectconInstead of creatingcontextObjects, although they are actually the same object. This is because the Block will make a strong reference to the Internally used objects created in the external definition, andJSContextStrong references will also be made to the given blocks, so that a Circular Reference (Circular Reference) will be formed between them so that the memory cannot be normally released.
    ForJSValueIt cannot be referenced directly from the external to the Block, because eachJSValueBoth haveJSContextReference (@property(readonly, retain) JSContext *context;),JSContextReferencing Block also forms a reference loop.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.