OC vs. JS interaction (JavaScriptCore Framework Introduction)

Source: Internet
Author: User
Tags javascript array

Former, Apple officially released the new iOS 7 system, the biggest and most intuitive change is the interface becomes small and fresh, I also mentioned "IOS, you are really more and more like Android." But for mobile developers, in addition to adapting to Xcode 5, the most important thing to focus on is the change in iOS 7 on the development interface. At a glance at Apple's official document "What's New in IOS", I'm most delighted with the addition of the JavaScriptCore framework to iOS 7. The framework makes the direct interaction of objective-c and JavaScript code easier and easier.

This framework is only based on the WebKit in a C + + implementation of the JavaScriptCore of a wrapper, in the previous version of iOS development, many developers will own WebKit library into the project compiled use. But although iOS7 it as a standard library, unfortunately, I haven't found an official document in Apple developer that describes how this framework is used, as it did in previous articles.

Fortunately, you can also find the header file in Xcode, and the comments inside the function of each class and method to write a clear, and then combined with the introduction of only a few articles on the Internet, I also here a simple introduction to the JavaScriptCore Framework on the basic data type use. In another article, "JavaScriptCore Framework for object interaction and management in IOS7," I'll go into more detail on the use of the framework on objects.

Classes in the JavaScriptCore

After the introduction of JavaScriptCore in the project, the chain header file, in addition to the large paragraph of the copyright note can be seen as long as the introduction of 5 files, each file is defined with the name of the corresponding class:

    • Jscontext
    • Jsvalue
    • Jsmanagedvalue
    • Jsvirtualmachine
    • Jsexport

Although the comments in the code are more detailed, the code is more convincing to the programmer, as is the case at the top of the graph. In this paper, we first say that these classes are relatively good to understand but also very common jscontext and jsvalue and their methods of use and effect.

Jscontext and Jsvalue

JSVirtualMachineProvides the underlying resources for JavaScript to run, JSContext provides a run-time environment, executes a - (JSValue *)evaluateScript:(NSString *)script; JavaScript script through a method, and, if there are methods, variables, and so on, is stored in it so that it can be used when needed. The creation of Jscontext is based on the JSVirtualMachine following: - (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine; if initialized with use - (id)init; , a new object is automatically created inside it JSVirtualMachine and then the initialization method in front of it is called.

JSValueCan be said to be a bridge between JavaScript and Object-c, which provides a variety of ways to easily convert JavaScript data types to objective-c, or to transform the past. The following table shows the corresponding methods:

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 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 Conversions

Let's look at a simple example:

1Jscontext *context =[[Jscontext alloc] init];2Jsvalue *jsval = [Context Evaluatescript:@"21+7"];3     intIval =[JsVal ToInt32];4NSLog (@"jsvalue:%@, int:%d", JsVal, ival);5      6     //Output:7     //jsvalue:28, int:28

Very simple, you can also save a JavaScript variable in the JSContext , and then through the subscript to get out. For the Array or Object type, JSValue you can also use the subscript to directly take the value and assignment.

1Jscontext *context =[[Jscontext alloc] init];2[Context Evaluatescript:@"var arr = [7, ' iderzheng.com '];"];3Jsvalue *jsarr = context[@"arr"];//Get array from Jscontext4      5NSLog (@"JS Array:%@; Length:%@", Jsarr, jsarr[@"length"]);6jsarr[1] =@"Blog";//Use Jsvalue as array7jsarr[7] = @7;8      9NSLog (@"JS Array:%@; Length:%d", Jsarr, [jsarr[@"length"] toInt32]);Ten       OneNsarray *nsarr =[Jsarr ToArray]; ANSLog (@"Nsarray:%@", Nsarr); -       -     //Output: the     //JS array:21,7,iderzheng.com Length:3 -     //JS array:21,blog,iderzheng.com,,,,, 7 length:8 -     //Nsarray: ( -     //, +     //Blog, -     //"Iderzheng.com", +     //"<null>", A     //"<null>", at     //"<null>", -     //"<null>", -     //7 -     // )

It is easy to see that the code successfully assigns the data from the objective-c to the JavaScript array, and JSValue follows the JavaScript array features: No subscript offside, automatic extension of the array size. JSValueYou can also get the properties on the JavaScript object, such as the length of the JavaScript array, as in the example "length" . In turn NSArray , all the information is correctly translated into the past.

Conversion of methods

Various data types can be converted, and objective-c blocks can also be passed into Jscontext as JavaScript methods. For example, in the front-end development of commonly used log methods, although javascritpcore no self-contained (after all, not on the Web page, Nature will not have window, document, console these classes), You can still define a block method to invoke NSLog to simulate:

1Jscontext *context =[[Jscontext alloc] init];2context[@"Log"] = ^() {3NSLog (@"+++++++begin log+++++++");4      5Nsarray *args =[Jscontext currentarguments];6      for(Jsvalue *jsvalinchargs) {7NSLog (@"%@", jsVal);8     }9      TenJsvalue * This=[Jscontext currentthis]; OneNSLog (@"This :%@", This); ANSLog (@"-------End Log-------"); -     }; -       the[Context Evaluatescript:@"log (' Ider ', [7, +], {hello: ' World ', js:100});"]; -       -     //Output: -     //+++++++begin log+++++++ +     //Ider -     //7,21 +     //[Object Object] A     //This : [Object Globalobject] at     //-------End Log-------

The successful use of block in JavaScript calls the method back to Objective-c, and still follows the various features of the JavaScript method, such as the method parameter is not fixed. Also because of this, JSContext a class method is provided to get the argument list ( + (JSContext *)currentContext; ) and the object that is currently calling the method ( + (JSValue *)currentThis ). For "this" , the content of the output is GlobalObject that this is JSContext what the object method - (JSValue *)globalObject; returns. Because we know that in JavaScript, all global variables and methods are actually properties of a global variable, and in the browser is a window, which is unknown in JavaScriptCore.

Blocks can be passed in JSContext as methods, but JSValue there is no toBlock way to turn JavaScript into blocks for use in objetive-c. After all, the number of parameters and the type of the block are fixed. Although it is not possible to extract the method, it JSValue provides a - (JSValue *)callWithArguments:(NSArray *)arguments; way to invoke the method in turn by passing the argument in.

1Jscontext *context =[[Jscontext alloc] init];2[Context Evaluatescript:@"function Add (A, B) {return a + B;}"];3Jsvalue *add = context[@"Add"];4NSLog (@"Func:%@", add);5      6Jsvalue *sum = [Add callwitharguments:@[@ (7), @( +)]];7NSLog (@"Sum:%d", [sum ToInt32]);8     //OutPut:9     //func:function Add (A, B) {return a + B;}Ten     //sum:28

JSValueIt also provides a - (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments; way for us to call directly on an object. Only if the method defined is a global function, it is obvious that the method should be JSContext called on the globalObject object, and if it is a method on a JavaScript object, it should be called with the appropriate JSValue object.

Exception handling

Objective-c exceptions are captured by Xcode at run time, and JSContext JavaScript executed in will only be captured and stored on attributes if an exception occurs, JSContext exception not thrown out. It is not always appropriate to check JSContext whether an object is exception not nil obvious, and a more reasonable way is to JSContext set the object exceptionHandler , which accepts the ^(JSContext *context, JSValue *exceptionValue) form block. Its default value is to assign the passed-in exceptionValue property to the passed in context exception :

1     ^ (Jscontext *context, Jsvalue *exceptionvalue) {2         context.exception = exceptionvalue; 3     };

We can also give a exceptionHandler new block so that we can immediately know when the JavaScript is running abnormally:

1Jscontext *context =[[Jscontext alloc] init];2Context.exceptionhandler = ^ (Jscontext *con, Jsvalue *exception) {3NSLog (@"%@", exception);4Con.exception =exception;5     };6      7[Context Evaluatescript:@"Ider.zheng ="];8      9     //Output:Ten     //Referenceerror:can ' t find Variable:ider

Precautions for using block

From the previous examples and presentations should have realized that block in JavaScriptCore play a powerful role, it between JavaScript and objective-c to build more bridges, make interoperability more convenient. However, it is important to note that whether the block is passed to the JSContext object to make it a JavaScript method, or if it is assigned to a exceptionHandler property, it is not allowed to use its externally defined object directly within the block JSContext or JSValue , It should be passed as a parameter to the block, or through JSContext a class method + (JSContext *)currentContext; . Otherwise, a circular reference causes the memory to not be freed properly.

For example, the top custom exception handling method is to assign incoming JSContext objects, con not objects created outside context them, although they are actually the same object. This is because block makes strong references to internally used objects created in the external definition, but JSContext also strong references to the given block, so that they form a circular reference (Circular Reference) that causes the memory to not be released properly.
It is also JSValue not possible to refer directly to the block from outside, because each JSValue JSContext of the references ( @property(readonly, retain) JSContext *context; ), and JSContext then the block will also form a reference loop.

Welcome to continue reading the JavaScriptCore framework for object interaction and management in iOS7 Learn more about the JavaScriptCore framework

References:
  1. Execute Javascript in IOS applications
  2. JavaScriptCore and IOS 7? Big Nerd Ranch blogbig Nerd Ranch Blog
  3. Steamclock Software–apple ' s new objective-c to Javascript Bridge
  4. Programming with OBJECTIVE-C: Working with Blocks
  5. Integrating JavaScript into Native applications–tracy e – push Cool

OC vs. JS interaction (JavaScriptCore Framework Introduction)

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.