madsmtm / objc2

Bindings to Apple's frameworks in Rust
https://docs.rs/objc2/
MIT License
280 stars 35 forks source link

Fix block2 memory management #568

Closed madsmtm closed 3 months ago

madsmtm commented 3 months ago

Part of https://github.com/madsmtm/objc2/issues/168. Fixes upstream https://github.com/SSheldon/rust-block/issues/9.

The way block2 currently works is that you create the StackBlock, and then you must call copy to convert it to an RcBlock. This is very error-prone, especially since you can't ensure that Objective-C doesn't call _Block_copy when you pass your stack block to an external function, so forgetting to call copy usually ends up causing double-frees.

Instead, we should implement StackBlock to use Clone once _Block_copy is called, and for the cases where that's impossible, the user should construct the RcBlock directly.

Clang notes: In ARC-enabled Clang, it is impossible to get the equivalent of StackBlock, since it effectively always does a .to_rc() on creation. Non-ARC Clang puts the block on the stack, and you're expected to call Block_copy yourself.