Closed
Description
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):
- 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) }
- 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)) } }) }
- 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