Как переводится мост ObjC JS?

Как платформа JavaScriptCore переводит объекты JavaScript в объекты Objective-C и наоборот? Использует ли мост один и тот же двоичный протокол для связи на обоих целевых языках?


person TMacGyver    schedule 13.04.2014    source источник


Ответы (2)


Платформа Objective-C, представленная в iOS7, сделает всю тяжелую работу за вас. Вам не нужно думать об объектах как об одном и том же двоичном файле, но интерпретируемом по-разному — платформа выполняет копирование при преобразовании между ObjC и Javascript.

Из JSValue.h:

// Conversion between Objective-C and JavaScript types.
//
// When converting between JavaScript values and Objective-C objects a copy is
// performed. Values of types listed below are copied to the corresponding
// types on conversion in each direction. For NSDictionaries, entries in the
// dictionary that are keyed by strings are copied onto a JavaScript object.
// For dictionaries and arrays, conversion is recursive, with the same object
// conversion being applied to all entries in the collection.

  Objective-C type  |   JavaScript type
--------------------+---------------------
        nil         |     undefined
       NSNull       |        null
      NSString      |       string
      NSNumber      |   number, boolean
    NSDictionary    |   Object object
      NSArray       |    Array object
       NSDate       |     Date object
      NSBlock *     |   Function object *
         id **      |   Wrapper object **
       Class ***    | Constructor object ***

* Instances of NSBlock with supported arguments types will be presented to
JavaScript as a callable Function object. For more information on supported
argument types see JSExport.h. If a JavaScript Function originating from an
Objective-C block is converted back to an Objective-C object the block will
be returned. All other JavaScript functions will be converted in the same
manner as a JavaScript object of type Object.

** For Objective-C instances that do not derive from the set of types listed
above, a wrapper object to provide a retaining handle to the Objective-C
instance from JavaScript. For more information on these wrapper objects, see
JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
the Objective-C instance being retained by the wrapper is returned.

*** For Objective-C Class objects a constructor object containing exported
class methods will be returned. See JSExport.h for more information on
constructor objects.

Например (для простых типов):

NSString *myString = [javascriptContext[@"myJSVar"] toString];

и

javascriptContext[@"myJSVar"] = myString;

или для более сложного объекта используйте протокол JSExport:

@protocol MyPointExports <JSExport>
@property double x;
@property double y;
@end

@interface MyPoint : NSObject <MyPointExports>
// Put methods and properties not visible to JavaScript code here.
@end

...

javascriptContext[@"MyPoint"] = [MyPoint class]; // Define the class in Javascript

потом

MyPoint *p = [javascriptContext[@"myJSPointVar"] toObject];

и

javascriptContext[@"myJSPointVar"] = p;

Для каждого свойства, объявленного в протоколе, фреймворк создаст JS-геттеры/сеттеры, поэтому внутри Javascript вы можете просто сделать:

myJSPointVar.x = 10;

Для тех читателей, которые ищут введение в структуру JavaScriptCore, ознакомьтесь с видео/pdf-сессией WWDC 2013 г. «Интеграция JavaScript в собственные приложения» в сети разработчиков Apple: https://developer.apple.com/videos/wwdc/2013/?id=615

person Mike    schedule 14.04.2014

Взгляните на этот класс: NSJSONSerialization.

person JE42    schedule 13.04.2014