#[repr(C)]pub struct StackBlock<'f, A, R, Closure> { /* private fields */ }Expand description
An Objective-C block constructed on the stack.
This can be a micro-optimization if you know that the function you’re
passing the block to won’t copy the block at all (e.g. if it guarantees
that it’ll run it synchronously). That’s very rare though, most of the
time you’ll want to use RcBlock.
This is a smart pointer that Derefs to Block.
§Type parameters
The type parameters for this is a bit complex due to trait system limitations. Usually, you will not need to specify them, as the compiler should be able to infer them.
- The lifetime
'f, which is the lifetime of the block. - The parameter
A, which is a tuple representing the parameters to the block. - The parameter
R, which is the return type of the block. - The parameter
Closure, which is the contained closure type. This is usually not nameable, and you will have to use_,impl Fn()or similar.
§Memory layout
The memory layout of this type is not guaranteed.
That said, it will always be safe to reinterpret pointers to this as a
pointer to a Block with the corresponding dyn Fn type.
Implementations§
Source§impl<'f, A, R, Closure> StackBlock<'f, A, R, Closure>
impl<'f, A, R, Closure> StackBlock<'f, A, R, Closure>
Sourcepub fn new(closure: Closure) -> Self
pub fn new(closure: Closure) -> Self
Construct a StackBlock with the given closure.
Note that this requires Clone, as a C block is generally assumed
to be copy-able. If you want to avoid that, put the block directly on
the heap using RcBlock::new.
When the block is called, it will return the value that results from calling the closure.
§Example
use block2::StackBlock;
let block = StackBlock::new(|a, b| a + b);
check_addition(&block);Sourcepub fn with_encoding<E>(closure: Closure) -> Selfwhere
E: ManualBlockEncoding<Arguments = A, Return = R>,
pub fn with_encoding<E>(closure: Closure) -> Selfwhere
E: ManualBlockEncoding<Arguments = A, Return = R>,
Constructs a new StackBlock with the given function and encoding
information.
Some particular newer-ish Apple Objective-C APIs expect the block they
are given to be created with encoding information set in the block
object itself and crash the calling process if they fail to find it,
which renders them pretty much unusable with only Self::new that
currently does not set such encoding information. This is for example
the case in FileProvider for NSFileProviderManager’s
reimportItemsBelowItemWithIdentifier:completionHandler: and
waitForStabilizationWithCompletionHandler:, but also in
NetworkExtension for NEFilterDataProvider’s
applySettings:completionHandler. A complete list of such APIs may
not be easily obtained, though.
This encoding information string could technically be generated at
compile time using the generic parameters already available to
Self::new. However, doing so would require some constant evaluation
features that are yet to be implemented and stabilized in the Rust
compiler. This function is therefore exposed in the meantime so users
may still be able to call the concerned APIs by providing the raw
encoding information string themselves, thus obtaining a block
containing it and working with these APIs.
You provide the encoding through the E type parameter, which should
implement ManualBlockEncoding.
The same requirements as Self::new apply here as well.
§Example
struct MyBlockEncoding;
// SAFETY: The encoding is correct.
unsafe impl ManualBlockEncoding for MyBlockEncoding {
type Arguments = (*mut NSError,);
type Return = i32;
const ENCODING_CSTR: &'static CStr = if cfg!(target_pointer_width = "64") {
cr#"i16@?0@"NSError"8"#
} else {
cr#"i8@?0@"NSError"4"#
};
}
let my_block = StackBlock::with_encoding::<MyBlockEncoding>(|_err: *mut NSError| {
42i32
});
assert_eq!(my_block.call((core::ptr::null_mut(),)), 42);Methods from Deref<Target = Block<Closure::Dyn>>§
Sourcepub fn copy(&self) -> RcBlock<F>
pub fn copy(&self) -> RcBlock<F>
Copy the block onto the heap as an RcBlock.
The behaviour of this function depends on whether the block is from a
RcBlock or a StackBlock. In the former case, it will bump the
reference-count (just as-if you’d Clone’d the RcBlock), in the
latter case it will construct a new RcBlock from the StackBlock.
This distinction should not matter, except for micro-optimizations.