-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More ergonomic references #95
Comments
A few more examples of usage: struct MyObject {
_data: [u8; 0], // Should maybe be UnsafeCell?
}
// On nightly:
extern type MyObject;
let obj: Owned<MyObject> = unsafe { Owned::new(msg_send![class!(MyObject), new]) };
let normal_reference: &MyObject = &*obj;
let mutable_reference: &mut MyObject = &mut *obj;
autoreleasepool(move |pool| {
let autoreleased_reference: &mut MyObject = retained.autorelease(pool);
// The reference lasts until here, and is deallocated afterwards
});
fn get_from_somewhere<'p>(pool: &'p AutoreleasePool) -> &'p MyObject {
unsafe {
let obj: *const MyObject = msg_send![class!(MyObject), get_from_somewhere];
&*obj
}
}
let retained: Retained<MyObject> = autoreleasepool(|pool| {
let obj: &MyObject = get_from_somewhere(pool);
Retained::retain(obj)
}); |
This was referenced May 28, 2021
This was referenced Sep 2, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Introduction
Hey, I've been thinking about how to make Objective-C's and Rust's memory models play nicer together.
Objective-C has two different "states" for references: Retained and autoreleased. In Rust there's the concept of ownership, which means we're the only place that holds a reference to that object - this is how we get safe mutability.
As such, in Rust, an Objective-C reference can be in a multitude of different "states":
In Rust we also have the borrow checker, so we can furthermore safely copy and return references without needing to retain and autorelease them first (provided they do not outlive the Objective-C reference).
The idea
I would like to propose an addition to
objc
that makes it possible to handle these references safely and ergonomically for users of the library. The idea is to add two smart pointers,Owned
andRetained
(names are up for bikeshedding), and modify theautoreleasepool
function to carry some lifetime information (this would be the only breaking change, and could easily be ignored for people who don't want it).See the following code snippets for a better explanation:
Retained and owned:
Retained and aliased:
Autoreleased and owned:
Autoreleased and aliased:
Library authors would then be able to create functions like
MyObject::new
that would return anOwned<MyObject>
andMyObject::get_from_somewhere
that would take a&'p AutoreleasePool
parameter, and return&'p MyObject
.For some of these things to be sound we'll need some nightly features or debug assertions (probably nightly features under a feature flag, debug assertions if not), but I think it's doable.
Outro
I'll be brewing a few PRs in the coming days, but would you, @SSheldon, welcome this addition? (Of course, it'll need modifications)
As a real-world usecase, I know there are several minor memory leaks in the MacOS backend of
winit
, but I haven't bothered to fix them because I know they will appear again after a refactor. Ifobjc
had some better mechanism for keeping track of references, like the one described in this issue (or if someone has a better idea), we would be able to eliminate most of these issues.The text was updated successfully, but these errors were encountered: