Skip to main content

objc_rs/rc/
strong.rs

1use std::fmt;
2use std::mem;
3use std::ops::Deref;
4
5use super::WeakPtr;
6use crate::runtime::{self, Object};
7
8/// A pointer that strongly references an object, ensuring it won't be deallocated.
9pub struct StrongPtr(*mut Object);
10
11impl StrongPtr {
12    /// Constructs a `StrongPtr` to a newly created object that already has a
13    /// +1 retain count. This will not retain the object.
14    /// When dropped, the object will be released.
15    /// Unsafe because the caller must ensure the given object pointer is valid.
16    pub unsafe fn new(ptr: *mut Object) -> Self {
17        StrongPtr(ptr)
18    }
19
20    /// Retains the given object and constructs a `StrongPtr` to it.
21    /// When dropped, the object will be released.
22    /// Unsafe because the caller must ensure the given object pointer is valid.
23    pub unsafe fn retain(ptr: *mut Object) -> Self {
24        StrongPtr(unsafe { runtime::objc_retain(ptr) })
25    }
26
27    /// Autoreleases self, meaning that the object is not immediately released,
28    /// but will be when the autorelease pool is drained. A pointer to the
29    /// object is returned, but its validity is no longer ensured.
30    pub fn autorelease(self) -> *mut Object {
31        let ptr = self.0;
32        mem::forget(self);
33        unsafe {
34            runtime::objc_autorelease(ptr);
35        }
36        ptr
37    }
38
39    /// Returns a `WeakPtr` to self.
40    pub fn weak(&self) -> WeakPtr {
41        unsafe { WeakPtr::new(self.0) }
42    }
43}
44
45impl Drop for StrongPtr {
46    fn drop(&mut self) {
47        unsafe {
48            runtime::objc_release(self.0);
49        }
50    }
51}
52
53impl Clone for StrongPtr {
54    fn clone(&self) -> StrongPtr {
55        unsafe { StrongPtr::retain(self.0) }
56    }
57}
58
59impl Deref for StrongPtr {
60    type Target = *mut Object;
61
62    fn deref(&self) -> &*mut Object {
63        &self.0
64    }
65}
66
67impl fmt::Pointer for StrongPtr {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        fmt::Pointer::fmt(&self.0, f)
70    }
71}