我有两个JSContext,并且我想不时在它们之间交换JSValue。但是,如果可能的话,我很难将JSValue移到新的上下文中。
我正在尝试:
newContext[@"newValue"] = [JSValue valueWithObject:newValue inContext:newContext];
尽管新上下文现在具有该值,但该值仍保留其旧上下文。不幸的是,它仍然保留其旧的环境。有什么建议么?
最佳答案
我建议您在新的上下文中创建新的JSValue之前,先将JSValue的值从其旧的javascript上下文中提取到一个普通的object-c对象中。查看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将保持 Activity 状态,同时保留旧的值)。您可能要通过以下方式删除此引用:
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.