使用JavascriptCore API
时,我不确定如何通过new
语法(ex. var x = new MyAwesomeClass())
从Javascript创建Objective-C对象的新实例。看来,在传递符合JSExport-derived protocol
的Objective-C类时,在Javascript中创建的构造函数对象应该可以作为构造函数调用,但它们不是。
例如,假设我有一个符合JSExport-derived protocol
的类,并将其插入到javascript上下文中:
@protocol MyAwesomeClassExports <JSExport>
...
@end
@interface MyAwesomeClass : NSObject <MyAwesomeClassExports>
...
@end
JSContext *context = ...;
context[@"MyAwesomeClass"] = [MyAwesomeClass class]
然后,如果我尝试通过以下语法在javascript中创建一个新实例:
[object MyAwesomeClassConstructor] is not a constructor
是否可以使用new
语法从javascript创建Objective-C对象的新实例?我理想的是将它alloc
,然后在Objective-C实例上调用init
方法。如果在javascript中传递了任何参数,那么希望通过[JSContext currentArguments]类方法可以在Objective-C init
方法中访问这些参数。
答案 0 :(得分:3)
这就是我一直在使用的。希望这有帮助!
extern void RHJSContextMakeClassAvailable(JSContext *context, Class class){
NSString *className = NSStringFromClass(class);
context[[NSString stringWithFormat:@"__%@", className]] = (id) ^(void){ return [[class alloc] init]; };
[context evaluateScript:[NSString stringWithFormat:@"var %@ = function (){ return __%@();};", className, className]];
//allow a class to perform other setup upon being loaded into a context.
SEL selector = NSSelectorFromString(@"classWasMadeAvailableInContext:");
if ([class respondsToSelector:selector]){
((void (*)(id, SEL, JSContext*))[class methodForSelector:selector])(class, selector, context);
}
}
答案 1 :(得分:3)
一个简单的解决方案是在Obj-C中定义构造函数。
// Inside protocol
+ (MyAwesomeClass *)create;
...
// Inside implementation
+ (MyAwesomeClass *)create
{
return [[MyAwesomeClass alloc] init];
}
然后在JavaScript中,只需调用此构造函数来创建一个新对象:
obj = MyAwesomeClass.create()
答案 2 :(得分:1)
我知道这很老了,但这对我有用:
context[@"MyClass"] = ^MyClass*{
return [[MyClass alloc] init];
};
然后来自JavaScript:
var myClass = new MyClass();
答案 3 :(得分:1)
为要从Javascript实例化的类创建协议。它应该扩展JSExport。
@import JavaScriptCore
@protocol EntityExports <JSExport>
@property NSString *somePropertyToExpose
- (instancetype)initWithSomeValue:(NSString *)value;
@end
@interface Enity : NSObject <EntityExports>
@end
并在.m文件中,实现初始化程序并合成属性:
@implementation Entity
@synthesize somePropertyToExpose = _somePropertyToExpose;
- (instancetype)initWithSomeValue:(NSString *)value
{
// implementation goes here
}
@end
然后,在实例化JSContext的代码中:
context[@"Entity"] = [Entity class];
并在Javascript中实例化Entity
:
var entity = new Entity("hello!");
(请注意,该属性不是构造对象所必需的;它只是为了使示例非平凡)。
答案 4 :(得分:0)
我不确定这个,但我认为你应该首先创建你的Objective-C对象,之后你应该像这样创建JSValue:
MyAwesomeClass *myClass = [[MyAwesomeClass alloc] init];
JSValue *dataValue = [JSValue valueWithObject: myClass inContext:context];
让我知道这是帮助。
答案 5 :(得分:0)
这个问题前几天在Apple开发者论坛中被问到here。
据我所知,看起来这是一个已知的缺陷,最近才在WebKit(包括JavaScriptCore)中修复;并且更改不在iOS7中:
https://bugs.webkit.org/show_bug.cgi?id=123380
通过使用JSObjectMake和正确配置的JSClassDefinition,可以在WebKit外部完成此操作吗?我没有时间调查这条路线。