【问题标题】:JavaScriptCore Won't Pass string as NSObject *JavaScriptCore 不会将字符串作为 NSObject 传递 *
【发布时间】:2014-04-15 19:28:53
【问题描述】:

考虑以下带有 NSObject * 属性的 JSExported Objective-c 类:

@protocol MyObjectExport <JSExport>
@property (nonatomic, strong) NSObject *myProperty;
@end

@interface MyObject : NSObject <MyObjectExport>
@end

@implementation MyObject
- (NSObject *)myProperty
{
    NSLog(@"in myProperty");
    return nullptr;
}
- (void)setMyProperty:(NSObject *)myProperty
{
    NSLog(@"in setMyProperty");
}
@end

如果我执行这段代码:

{
    JSContext *context = [[JSContext alloc] init];
    context[@"myObject"] = [[MyObject alloc] init];
    [context evaluateScript:@"var foo = myObject.myProperty; myObject.myProperty = foo;"];
}

myProperty 和 setMyProperty 都被调用。

但是如果我执行这段代码:

{
    JSContext *context = [[JSContext alloc] init];
    context[@"myObject"] = [[MyObject alloc] init];
    [context evaluateScript:@"myObject.myProperty = \"foo\";"];
}

setMyProperty 没有被调用,大概是因为 "foo" 与 NSObject * 不兼容。

但是,如果我执行这段代码:

{
    MyObject *myObject = [[MyObject alloc] init];
    myObject.myProperty = @"foo";
}

setMyProperty 被调用。

当然,如果我用 NSString * 替换 NSObject *,一切正常。但我需要这个属性才能容纳各种对象类型。

我不控制传递给 evaluateScript 的内容。但是,有没有一种方法可以编写代码,以便 JavaScriptCore 在将“foo”传递给 Objective-c 回调之前将其普遍转换为 NSString *?我意识到我可以在 javascript 端拦截调用并在那里进行必要的摆弄,但如果可能的话,我想避免这种情况。

【问题讨论】:

    标签: javascript ios javascriptcore


    【解决方案1】:

    如果您需要持有多种类型中的一种,您应该使用id 而不是NSObject *。这将使它成为一个通用指针,类似于 C 中的 void *

    更好的是,您可以使用JSValue * 作为类型,因为-[JSValue is*] 消息可以帮助您确定实际传递的类型。这样做的缺点是您的JSValue * 属性需要由JSManagedValue * ivars 支持以防止保留周期。有关此内存管理问题的更多信息,请参阅 WWDC 2013 视频 615,大约 2/3。

    【讨论】:

    • 他不应该将 JSValue 作为objective-c 对象的属性。这将导致保留周期。不过,他可以使用 JSManagedValue。
    • @TechZen 您可以使用 JSValue 作为属性,实际上视频也是如此。请记住,属性的类型只是 setter 采用和 getter 返回的类型,不一定是用于存储属性的 ivar 的类型。拥有访问 JSManagedValue 类型的 ivars 的 JSValue 类型的属性很容易。这就是我的建议的目的。
    • 啊,是的,你可以,虽然这似乎是一个让你大吃一惊的好方法。
    • @TechZen 我很不同意。面向对象编程的思想是通过封装将接口与实现分离。引入 JSManagedValue 是为了解决存储问题,但是您的类的用户不(也不应该)关心您如何存储 JSValue(通过 JSManagedValue ivar,实现),只关心如何访问它们(通过 JSValue 属性,界面)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多