Skip to content

Better autorelease ergonomics #86

Description

@madsmtm

The ergonomics of using autoreleased references are not great, especially when you are creating your own class. We should try to do better!

I see mainly three use-cases (for library / binding creators; end users probably won't touch this part of the library):

  1. Returning a reference (shared in the example, could also be mutable)
    pub fn description<'pool>(&self, pool: &'pool AutoreleasePool) -> &'pool NSString {
        let desc: *const NSString = msg_send![self, description];
        pool.ptr_as_ref(desc)
    }
  2. Exposing a retained version of the above:
    pub fn description_retained<'pool>(&self, pool: &'pool AutoreleasePool) -> Id<NSString, Shared> {
        // SAFETY: The NSString is valid and not mutably owned anywhere
        // The unsafe is required because the `&NSString` could have come from an `Id<NSString, Owned>`.
        unsafe { Id::retain(self.description(pool)) }
    }
    // Or
    pub fn description_retained(&self) -> Id<NSString, Shared> {
        autoreleasepool(|pool| {
            unsafe { Id::retain(self.description(pool)) }
        })
    }
  3. Returning an autoreleased object in a custom / overridden method:
    extern "C" valid_attributes(_this: &Object, _sel: Sel) -> *mut NSArray {
        let array = Id<NSArray, Owned>::from(vec![...]);
        array.autorelease(pool) // Uhh, we don't have a pool from anywhere; it is implicit in Objective-C
    }
    let mut decl = ClassDecl::new("MyView", class!(NSView)).unwrap();
    decl.add_method(
        sel!(validAttributesForMarkedText),
        valid_attributes as extern "C" fn(&Object, Sel) -> *mut NSArray,
    );

See related: gfx-rs/metal-rs#222

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions