lukaskollmer / objc

🔮 NodeJS ↔ Objective-C bridge (experimental)
MIT License
98 stars 20 forks source link

NSInvalidArgumentException calling a method with a dispatch_queue_t argument #6

Closed jmbldwn closed 6 years ago

jmbldwn commented 6 years ago

I'm getting an exception when calling AVCaptureVideoDataOutput.setSampleBufferDelegate_queue_(delegate, queue).

While I am able to call other AVCaptureSession-related methods, this one throws an exception.

Two possible differences: 1) I am passing it my own custom class as a delegate. 2) I am passing it a dispatch_queue_t argument I got from calling dispatch_queue_create using ffi.

In both cases I may not entirely know what I'm doing, but I think I'm setting up these arguments correctly.

I distilled the problem down in this gist:

https://gist.github.com/jmbldwn/0ca994f69ed9f7d0e5adcef2bb4c1e4f

The exception is triggered by the call to runtime.msgSend(types[returnType], argumentTypes); at line 97 of instance.js.

Call stack:

Exception has occurred: Error
Error: NSInvalidArgumentException *** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: get)
    at Instance.call (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:110:13)
    at Object.apply (/Users/jim/development/node/objc/test/node_modules/objc/src/proxies.js:21:19)
    at Function.ns (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:249:20)
    at argv.map (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:90:31)
    at Array.map (<anonymous>)
    at Instance.call (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:68:23)
    at Object.apply (/Users/jim/development/node/objc/test/node_modules/objc/src/proxies.js:21:19)
    at Function.ns (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:249:20)
    at argv.map (/Users/jim/development/node/objc/test/node_modules/objc/src/instance.js:90:31)
    at Array.map (<anonymous>)

Anything else I should be trying?

lukaskollmer commented 6 years ago

the issue is that you're passing the "raw" object returned from dispatch_queue_create to setSampleBufferDelegate:queue:. the objc module expects all id parameters to be a objc.InstanceProxy wrapping an objc.Instance.

you can use the objc.wrap helper function to achieve this: simply replace the dispatch queue creation line w/ the following:

let queue = objc.wrap(c.dispatch_queue_create('myQueue', null));
jmbldwn commented 6 years ago

This solved my problem. Woot!