3
3
//! The utilities of the `rc` module provide ARC-like semantics for working
4
4
//! with Objective-C's reference counted objects in Rust.
5
5
//!
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.
16
8
//!
17
9
//! To enforce aliasing rules, an `Id` can be either owned or shared; if it is
18
10
//! owned, meaning the `Id` is the only reference to the object, it can be
33
25
//! [mem-mgmt]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
34
26
//! [mem-cf]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/CFMemoryMgmt.html
35
27
//! [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
- //! ```
60
28
61
29
mod autorelease;
62
30
mod id;
63
31
mod ownership;
64
- mod strong;
65
- mod weak;
66
32
mod weak_id;
67
33
68
34
pub use self :: autorelease:: { autoreleasepool, AutoreleasePool , AutoreleaseSafe } ;
69
35
pub use self :: id:: { Id , ShareId } ;
70
36
pub use self :: ownership:: { Owned , Ownership , Shared } ;
71
- pub use self :: strong:: StrongPtr ;
72
- pub use self :: weak:: WeakPtr ;
73
37
pub use self :: weak_id:: WeakId ;
74
38
75
- // These tests use NSObject, which isn't present for GNUstep
76
- #[ cfg( all( test, target_vendor = "apple" ) ) ]
39
+ #[ cfg( test) ]
77
40
mod tests {
78
41
use core:: mem:: size_of;
79
42
80
- use super :: autoreleasepool;
81
- use super :: StrongPtr ;
82
43
use super :: { Id , Owned , Shared , WeakId } ;
83
- use crate :: runtime:: Object ;
84
44
85
45
pub struct TestType {
86
46
_data : [ u8 ; 0 ] , // TODO: `UnsafeCell`?
@@ -104,65 +64,4 @@ mod tests {
104
64
size_of:: <* const ( ) >( )
105
65
) ;
106
66
}
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
- }
168
67
}
0 commit comments