Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to pass function? #269

Closed
kanatapple opened this issue Sep 14, 2022 · 5 comments
Closed

Question: How to pass function? #269

kanatapple opened this issue Sep 14, 2022 · 5 comments
Labels
A-block2 Affects the `block2` crate question Further information is requested

Comments

@kanatapple
Copy link

Hi, How can I pass a function to msg_send and call it?
For example, I want to pass a function to the completionHandler of setCookie method in WKHTTPCookieStore like in the code below.

// https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882007-setcookie?language=objc
msg_send![http_cookie_store, cookie: cookie_data, completionHandler: function];

I don't know how to define function.

I'm actually using objc, but this community is more active so I asked here.

@madsmtm
Copy link
Owner

madsmtm commented Sep 16, 2022

The completionHandler argument is not a function, rather, it is a "block" (see this for details, essentially the C-equivalent of a Rust dyn Fn closure).

So to call it, you'd do something like this:

use block2::{Block, ConcreteBlock}; // or the old `block` crate

let handler = ConcreteBlock::new(|| {
    // Code to run on completion.
    // This closure can capture values, but since `completionHandler` is executed asynchronously, the captured
    // values must be `Send + Sync`.
});
// Put the block on the heap
let handler = handler.copy();
// Ensure that the block has the correct type (no arguments, `void` return type)
let handler: &Block<(), ()> = &handler;

let _: () = unsafe { msg_send![http_cookie_store, cookie: cookie_data, completionHandler: handler] };

@madsmtm
Copy link
Owner

madsmtm commented Sep 16, 2022

(I know that the API that the block2 crate exposes is not really that nice to work with, I am working on improving this, see #168)

@madsmtm madsmtm added question Further information is requested A-block2 Affects the `block2` crate labels Sep 16, 2022
@kanatapple
Copy link
Author

Thanks. I will try.

@kanatapple
Copy link
Author

It's working as expected.
Thank you.

@silvanshade
Copy link
Contributor

silvanshade commented Jan 8, 2023

@madsmtm Is the example above still how one is supposed to pass a block as an argument? It doesn't seem to work with the published crates (block2 = "0.1.6" and icrate = "0.0.1").

With the following simplified example, I get an error:

EDIT: Oh, I just realized the issue was due to using an outdated/conflicting versions of block2 with icrate. Working now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-block2 Affects the `block2` crate question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants