Skip to content

Commit e08e87d

Browse files
committed
Remove StrongPtr and WeakPtr
We want to encourage users to use Id and WeakId, because they provide much stronger guarantees. The other types can in most cases be emulated as: type StrongPtr = Option<Id<Object, Shared>> type WeakPtr = WeakId<Object> And for the cases where they can't, their implementation is pretty simple anyhow, so advanced users can just use objc2_sys to implement the functionality they need themselves.
1 parent 470a4b7 commit e08e87d

File tree

8 files changed

+64
-257
lines changed

8 files changed

+64
-257
lines changed

objc2/README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,33 @@ unsafe {
2929

3030
The utilities of the `rc` module provide ARC-like semantics for working with
3131
Objective-C's reference counted objects in Rust.
32-
A `StrongPtr` retains an object and releases the object when dropped.
33-
A `WeakPtr` will not retain the object, but can be upgraded to a `StrongPtr`
34-
and safely fails if the object has been deallocated.
32+
33+
An `Id` retains an object and releases the object when dropped.
34+
A `WeakId` will not retain the object, but can be upgraded to an `Id` and
35+
safely fails if the object has been deallocated.
3536

3637
```rust , no_run
3738
use objc2::{class, msg_send};
38-
use objc2::rc::{autoreleasepool, StrongPtr};
39+
use objc2::rc::{autoreleasepool, Id, Shared, WeakId};
40+
use objc2::runtime::Object;
3941

40-
// StrongPtr will release the object when dropped
41-
let obj = unsafe {
42-
StrongPtr::new(msg_send![class!(NSObject), new])
42+
// Id will release the object when dropped
43+
let obj: Id<Object, Shared> = unsafe {
44+
Id::new(msg_send![class!(NSObject), new])
4345
};
4446

4547
// Cloning retains the object an additional time
4648
let cloned = obj.clone();
47-
autoreleasepool(|_| {
48-
// Autorelease consumes the StrongPtr, but won't
49+
autoreleasepool(|pool| {
50+
// Autorelease consumes the Id, but won't
4951
// actually release until the end of an autoreleasepool
50-
cloned.autorelease();
52+
let obj_ref: &Object = cloned.autorelease(pool);
5153
});
5254

5355
// Weak references won't retain the object
54-
let weak = obj.weak();
56+
let weak = WeakId::new(&obj);
5557
drop(obj);
56-
assert!(weak.load().is_null());
58+
assert!(weak.load().is_none());
5759
```
5860

5961
## Declaring classes

objc2/examples/introspection.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use objc2::rc::StrongPtr;
1+
use core::ptr::NonNull;
2+
3+
use objc2::rc::{Id, Owned};
24
use objc2::runtime::{Class, Object};
35
use objc2::{class, msg_send, sel, Encode};
46

@@ -14,15 +16,15 @@ fn main() {
1416
}
1517

1618
// Allocate an instance
17-
let obj = unsafe {
19+
let obj: Id<Object, Owned> = unsafe {
1820
let obj: *mut Object = msg_send![cls, alloc];
19-
let obj: *mut Object = msg_send![obj, init];
20-
StrongPtr::new(obj)
21+
let obj: NonNull<Object> = msg_send![obj, init];
22+
Id::new(obj)
2123
};
2224
println!("NSObject address: {:p}", obj);
2325

2426
// Access an ivar of the object
25-
let isa: *const Class = unsafe { *(**obj).get_ivar("isa") };
27+
let isa: *const Class = unsafe { *obj.get_ivar("isa") };
2628
println!("NSObject isa: {:?}", isa);
2729

2830
// Inspect a method of the class
@@ -33,6 +35,6 @@ fn main() {
3335
assert!(*hash_return == usize::ENCODING);
3436

3537
// Invoke a method on the object
36-
let hash: usize = unsafe { msg_send![*obj, hash] };
38+
let hash: usize = unsafe { msg_send![obj, hash] };
3739
println!("NSObject hash: {}", hash);
3840
}

objc2/src/exception.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
use crate::rc::StrongPtr;
1+
use core::ptr::NonNull;
2+
3+
use crate::rc::Id;
24
use crate::runtime::Object;
5+
use objc2_exception::{r#try, Exception};
36

47
// Comment copied from `objc2_exception`
58

@@ -18,6 +21,6 @@ use crate::runtime::Object;
1821
/// undefined behaviour until `C-unwind` is stabilized, see [RFC-2945].
1922
///
2023
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
21-
pub unsafe fn catch_exception<R>(closure: impl FnOnce() -> R) -> Result<R, StrongPtr> {
22-
objc2_exception::r#try(closure).map_err(|exception| StrongPtr::new(exception as *mut Object))
24+
pub unsafe fn catch_exception<R>(closure: impl FnOnce() -> R) -> Result<R, Id<Exception>> {
25+
r#try(closure).map_err(|e| Id::new(NonNull::new(e).unwrap()))
2326
}

objc2/src/rc/id.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,13 +517,29 @@ mod tests {
517517
use core::ptr::NonNull;
518518

519519
use super::{Id, Shared};
520+
use crate::rc::autoreleasepool;
520521
use crate::runtime::Object;
521522
use crate::{class, msg_send};
522523

523524
fn retain_count(obj: &Object) -> usize {
524525
unsafe { msg_send![obj, retainCount] }
525526
}
526527

528+
#[test]
529+
fn test_autorelease() {
530+
let obj: Id<Object, Shared> = unsafe { Id::new(msg_send![class!(NSObject), new]) };
531+
532+
let cloned = obj.clone();
533+
534+
autoreleasepool(|pool| {
535+
let _ref = obj.autorelease(pool);
536+
assert_eq!(retain_count(&*cloned), 2);
537+
});
538+
539+
// make sure that the autoreleased value has been released
540+
assert_eq!(retain_count(&*cloned), 1);
541+
}
542+
527543
#[test]
528544
fn test_clone() {
529545
let cls = class!(NSObject);

objc2/src/rc/mod.rs

Lines changed: 3 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,8 @@
33
//! The utilities of the `rc` module provide ARC-like semantics for working
44
//! with Objective-C's reference counted objects in Rust.
55
//!
6-
//! A `StrongPtr` retains an object and releases the object when dropped.
7-
//! A `WeakPtr` will not retain the object, but can be upgraded to a `StrongPtr`
8-
//! and safely fails if the object has been deallocated.
9-
//!
10-
//! These utilities are not intended to provide a fully safe interface, but can be
11-
//! useful when writing higher-level Rust wrappers for Objective-C code.
12-
//!
13-
//! A smart pointer version of this is provided with the `Id` struct.
14-
//! To ensure that Objective-C objects are retained and released
15-
//! at the proper times.
6+
//! A smart pointer [`Id`] is provided to ensure that Objective-C objects are
7+
//! retained and released at the proper times.
168
//!
179
//! To enforce aliasing rules, an `Id` can be either owned or shared; if it is
1810
//! owned, meaning the `Id` is the only reference to the object, it can be
@@ -33,54 +25,22 @@
3325
//! [mem-mgmt]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
3426
//! [mem-cf]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/CFMemoryMgmt.html
3527
//! [mem-debug]: https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html
36-
//!
37-
//! # Example
38-
//!
39-
//! ``` no_run
40-
//! # use objc2::{class, msg_send};
41-
//! # use objc2::rc::{autoreleasepool, StrongPtr};
42-
//! // StrongPtr will release the object when dropped
43-
//! let obj = unsafe {
44-
//! StrongPtr::new(msg_send![class!(NSObject), new])
45-
//! };
46-
//!
47-
//! // Cloning retains the object an additional time
48-
//! let cloned = obj.clone();
49-
//! autoreleasepool(|_| {
50-
//! // Autorelease consumes the StrongPtr, but won't
51-
//! // actually release until the end of an autoreleasepool
52-
//! cloned.autorelease();
53-
//! });
54-
//!
55-
//! // Weak references won't retain the object
56-
//! let weak = obj.weak();
57-
//! drop(obj);
58-
//! assert!(weak.load().is_null());
59-
//! ```
6028
6129
mod autorelease;
6230
mod id;
6331
mod ownership;
64-
mod strong;
65-
mod weak;
6632
mod weak_id;
6733

6834
pub use self::autorelease::{autoreleasepool, AutoreleasePool, AutoreleaseSafe};
6935
pub use self::id::{Id, ShareId};
7036
pub use self::ownership::{Owned, Ownership, Shared};
71-
pub use self::strong::StrongPtr;
72-
pub use self::weak::WeakPtr;
7337
pub use self::weak_id::WeakId;
7438

75-
// These tests use NSObject, which isn't present for GNUstep
76-
#[cfg(all(test, target_vendor = "apple"))]
39+
#[cfg(test)]
7740
mod tests {
7841
use core::mem::size_of;
7942

80-
use super::autoreleasepool;
81-
use super::StrongPtr;
8243
use super::{Id, Owned, Shared, WeakId};
83-
use crate::runtime::Object;
8444

8545
pub struct TestType {
8646
_data: [u8; 0], // TODO: `UnsafeCell`?
@@ -104,65 +64,4 @@ mod tests {
10464
size_of::<*const ()>()
10565
);
10666
}
107-
108-
#[test]
109-
fn test_strong_clone() {
110-
fn retain_count(obj: *mut Object) -> usize {
111-
unsafe { msg_send![obj, retainCount] }
112-
}
113-
114-
let obj = unsafe { StrongPtr::new(msg_send![class!(NSObject), new]) };
115-
assert!(retain_count(*obj) == 1);
116-
117-
let cloned = obj.clone();
118-
assert!(retain_count(*cloned) == 2);
119-
assert!(retain_count(*obj) == 2);
120-
121-
drop(obj);
122-
assert!(retain_count(*cloned) == 1);
123-
}
124-
125-
#[test]
126-
fn test_weak() {
127-
let obj = unsafe { StrongPtr::new(msg_send![class!(NSObject), new]) };
128-
let weak = obj.weak();
129-
130-
let strong = weak.load();
131-
assert!(*strong == *obj);
132-
drop(strong);
133-
134-
drop(obj);
135-
assert!(weak.load().is_null());
136-
}
137-
138-
#[test]
139-
fn test_weak_copy() {
140-
let obj = unsafe { StrongPtr::new(msg_send![class!(NSObject), new]) };
141-
let weak = obj.weak();
142-
143-
let weak2 = weak.clone();
144-
145-
let strong = weak.load();
146-
let strong2 = weak2.load();
147-
assert!(*strong == *obj);
148-
assert!(*strong2 == *obj);
149-
}
150-
151-
#[test]
152-
fn test_autorelease() {
153-
let obj = unsafe { StrongPtr::new(msg_send![class!(NSObject), new]) };
154-
155-
fn retain_count(obj: *mut Object) -> usize {
156-
unsafe { msg_send![obj, retainCount] }
157-
}
158-
let cloned = obj.clone();
159-
160-
autoreleasepool(|_| {
161-
obj.autorelease();
162-
assert!(retain_count(*cloned) == 2);
163-
});
164-
165-
// make sure that the autoreleased value has been released
166-
assert!(retain_count(*cloned) == 1);
167-
}
16867
}

objc2/src/rc/strong.rs

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)