Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MOJavaScriptObject function execution
@import JavaScriptCore;
/// Retaining MOJavaScriptObject retains your JSContext/JSObject as well
@interface MOJavaScriptObject : NSObject
@property (readonly) JSObjectRef JSObject;
@property (readonly) JSContextRef JSContext;
@end
@@implementation MOJavaScriptObject ()
- (JSValue*) callWithArguments:(NSArray*)argumentsArray {
JSContext *context = [JSContext contextWithJSGlobalContextRef:(JSGlobalContextRef)self.JSContext];
JSValue *function = [JSValue valueWithJSValueRef:self.JSObject inContext:context];
return [function callWithArguments:argumentsArray];
}
@end
@jamztang

This comment has been minimized.

Show comment
Hide comment
@jamztang

jamztang Mar 28, 2017

Thanks Matt, in additional to the original questions, I was trying to execute the code in background. I dispatched the operation in a global queue caused crash, even main thread caused crash. Would you happen to have some pointers for me on that?

// This works
- (void)runSomething:(MOJavaScriptObject *)closure {
    NSArray *args = @[@1, @3];
    JSContext *ctx = [JSContext contextWithJSGlobalContextRef:(JSGlobalContextRef)closure.JSContext];
    JSObjectRef fn = [closure JSObject];
    JSValue *value = [JSValue valueWithJSValueRef:fn inContext:ctx];
    JSValue *result = [value callWithArguments:args];   // result = 4

    NSLog(@"result %@", [result toString]);    // prints "result 4";
}


// This version is causing crash
- (void)runSomething:(MOJavaScriptObject *)closure  {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSArray *args = @[@1, @3];
        JSContext *ctx = [JSContext contextWithJSGlobalContextRef:(JSGlobalContextRef)closure.JSContext];
        JSObjectRef fn = [closure JSObject];
        JSValue *value = [JSValue valueWithJSValueRef:fn inContext:ctx];
        JSValue *result = [value callWithArguments:args];       // cause crash here

        NSLog(@"result %@", [result toString]);
    });
}

jamztang commented Mar 28, 2017

Thanks Matt, in additional to the original questions, I was trying to execute the code in background. I dispatched the operation in a global queue caused crash, even main thread caused crash. Would you happen to have some pointers for me on that?

// This works
- (void)runSomething:(MOJavaScriptObject *)closure {
    NSArray *args = @[@1, @3];
    JSContext *ctx = [JSContext contextWithJSGlobalContextRef:(JSGlobalContextRef)closure.JSContext];
    JSObjectRef fn = [closure JSObject];
    JSValue *value = [JSValue valueWithJSValueRef:fn inContext:ctx];
    JSValue *result = [value callWithArguments:args];   // result = 4

    NSLog(@"result %@", [result toString]);    // prints "result 4";
}


// This version is causing crash
- (void)runSomething:(MOJavaScriptObject *)closure  {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSArray *args = @[@1, @3];
        JSContext *ctx = [JSContext contextWithJSGlobalContextRef:(JSGlobalContextRef)closure.JSContext];
        JSObjectRef fn = [closure JSObject];
        JSValue *value = [JSValue valueWithJSValueRef:fn inContext:ctx];
        JSValue *result = [value callWithArguments:args];       // cause crash here

        NSLog(@"result %@", [result toString]);
    });
}
@nikogu

This comment has been minimized.

Show comment
Hide comment
@nikogu

nikogu Apr 4, 2018

@jamztang can you paste your closure code witch is how you trigger the runSomething method.

nikogu commented Apr 4, 2018

@jamztang can you paste your closure code witch is how you trigger the runSomething method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment