Function objc2::rc::autoreleasepool_leaking

source ·
pub fn autoreleasepool_leaking<T, F>(f: F) -> T
where for<'pool> F: FnOnce(AutoreleasePool<'pool>) -> T,
Expand description

Execute f in the context of a “fake” autorelease pool.

This is useful to create a context in which to use autoreleased objects, without the overhead of actually creating and draining the pool.

Any function boundary in Objective-C is an implicit autorelease pool, so there you’d do id obj2 = [obj autorelease] and be done with it - but we do this using a closure instead because we need some way to bind the lifetime of any objects released to the pool.

§Examples

Autorelease an object to an outer pool, from inside an inner, “fake” pool.

use objc2::rc::{autoreleasepool, autoreleasepool_leaking, Retained};
use objc2::runtime::NSObject;

autoreleasepool(|outer_pool| {
    let obj = autoreleasepool_leaking(|inner_pool| {
        Retained::autorelease(NSObject::new(), outer_pool)
    });
    // `obj` is still usable here, since the leaking pool doesn't actually
    // do anything.
    println!("{obj:?}");
});

// But it is not usable here, since the outer pool has been closed

Like autoreleasepool, you can’t extend the lifetime of an object to outside the closure.

use objc2::rc::{autoreleasepool_leaking, Retained};
use objc2::runtime::NSObject;

let obj = autoreleasepool_leaking(|pool| {
    Retained::autorelease(NSObject::new(), pool)
});

While you can pass an outer pool into this, you still can’t pass the pool from this into autoreleasepool:

use objc2::rc::{autoreleasepool, autoreleasepool_leaking, Retained};
use objc2::runtime::NSObject;

autoreleasepool_leaking(|outer_pool| {
    let obj = autoreleasepool(|inner_pool| {
        Retained::autorelease(NSObject::new(), outer_pool)
    });
});