Есть ли способ переместить JSValue в новый JSContext, игнорируя его первоначальный контекст?
У меня есть два JSContexts, и я хочу время от времени обмениваться JSValues между ними. Тем не менее, мне трудно переместить JSValue в новый контекст, если это возможно.
Я пытаюсь это:
newContext[@"newValue"] = [JSValue valueWithObject:newValue inContext:newContext];
В то время как новый контекст теперь имеет это значение, значение все еще сохраняет свой старый контекст. К сожалению, он все еще сохраняет свой старый контекст. Какие-либо предложения?
2 ответа
Я предлагаю вам извлечь значение JSValue из его старого контекста javascript в обычный объект target-c перед созданием нового JSValue в новом контексте. Изучение JSValue.h показывает, что класс JSValue имеет свойство только для чтения, которое содержит JSContext, из которого происходит значение.
Я не могу сказать, с каким типом значения вы имеете дело из приведенного выше кода, но, например, (для простых типов):
NSString *newString = [newValue toString]; // Extract from old JSValue
newContext[@"newValue"] = newString;
или для более сложного объекта:
@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
newcontext[@"MyPoint"] = [MyPoint class]; // Define the class in Javascript
...
MyPoint *p = [newValue toObject]; // Extract from old JSValue
newContext[@"newValue"] = p;
Обратите внимание, что значение все еще будет существовать в старом JSContext (старый JSContext останется живым, пока сохраняется старое значение). Вы можете удалить эту ссылку:
oldContext[@"oldValue"] = nil; // Assuming the var in the oldContext was called oldValue
Обратите внимание, что вам не нужно использовать конструктор:
+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;
поскольку JavaScriptCore имеет встроенную конвертацию для следующего (см. JSValue.h):
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.
На самом деле вам не нужно беспокоиться о контексте в JSValue. Если вы поместите точку останова в код JavaScript, вы увидите, что объект, переданный из Native, не имеет свойства context. Контекст в JSValue предназначен только для отображения оригинального JSContext и на самом деле не ссылается на него.