【问题标题】:JavaScriptCore -- Passing a function as a parameter to ObjCJavaScriptCore -- 将函数作为参数传递给 ObjC
【发布时间】:2014-04-01 15:31:17
【问题描述】:

我有一个使用 JavaScriptCore 的 UIWebView。我正在尝试从网页调用 ObjC 函数。但是,该函数需要异步调用,因此我传入了一个回调函数,该函数在调用异步 ObjC 函数时调用。

据我了解,JS函数通过桥接相当于NSBlock。我目前的代码是:

context[@"currentUserLocation"] = ^( void(^callback)(NSString* str) )
{
    NSLog(@"Starting Async Function");

    //generic async function
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"delay complete");
        callback( @"return value" );
    });
};

我正在做的事情有什么根本错误吗?从表面上看,ObjC 似乎不知道在什么上下文中运行回调函数。

【问题讨论】:

    标签: javascript ios objective-c uiwebview javascriptcore


    【解决方案1】:

    我花了一点时间才掌握了这个窍门。诀窍是不要将回调参数视为一个块,而是一个 JSValue,然后使用 JSValue API 调用它:

    context[@"currentUserLocation"] = ^(JSValue *callback)
    {
        NSLog(@"Starting Async Function");
    
        //generic async function
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"delay complete");
            //Check we actually have a callback (isObject is the best we can do, there is no isFunction)
            if ([callback isObject] != NO) {
                //Use window.setTimeout to schedule the callback to be run
                [context[@"setTimeout"] callWithArguments:@[callback, @0, @"return value"]];
            }
        });
    };
    

    在 window.setTimeout() 调用中包装回调允许 JSVirtualMachine 处理调度和线程,我发现如果回调完成任何 UI 工作,直接调用回调通常会导致死锁。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2012-02-11
    • 2021-01-02
    • 1970-01-01
    相关资源
    最近更新 更多