Skip to content

Commit 0a6e8b6

Browse files
committed
Merge objc2_id into objc2
Id is such a vital requirement for applications that there's no need to make it a "second class citizen". If we really feel it's too much of an experiment, we can always feature-flag it later. Also, there's might be traits I'd like to implement for e.g. Option<Id> that is not possible if it lives in it's own crate!
1 parent b980a1f commit 0a6e8b6

File tree

15 files changed

+104
-173
lines changed

15 files changed

+104
-173
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ members = [
66
"objc2_exception",
77
"objc2_foundation",
88
"objc2_foundation_derive",
9-
"objc2_id",
109
"objc2_sys",
1110
"objc2_test_utils",
1211
]

objc2/src/macros.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,15 @@ macro_rules! sel {
6666
Sends a message to an object.
6767
6868
The first argument can be any type that dereferences to a type that implements
69-
[`Message`], like a reference, a pointer, or an `objc2_id::Id` to an object.
69+
[`Message`], like a reference, a pointer, or an [`rc::Id`] to an
70+
object.
7071
7172
The syntax is similar to the message syntax in Objective-C.
7273
7374
Variadic arguments are not currently supported.
7475
7576
[`Message`]: crate::Message
77+
[`rc::Id`]: crate::rc::Id
7678
7779
# Panics
7880

objc2_id/src/id.rs renamed to objc2/src/rc/id.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use core::ops::{Deref, DerefMut};
1010
use core::ptr;
1111
use core::ptr::NonNull;
1212

13-
use objc2::rc::AutoreleasePool;
14-
use objc2::Message;
13+
use super::AutoreleasePool;
14+
use crate::Message;
1515

1616
/// A type used to mark that a struct owns the object(s) it contains,
1717
/// so it has the sole references to them.
@@ -84,9 +84,33 @@ impl Ownership for Shared {}
8484
/// # Examples
8585
///
8686
/// ```no_run
87+
/// use objc2::msg_send;
88+
/// use objc2::runtime::{Class, Object};
89+
/// use objc2::rc::{Id, WeakId, Shared};
90+
///
91+
/// let cls = Class::get("NSObject").unwrap();
92+
/// let obj: Id<Object> = unsafe {
93+
/// Id::new(msg_send![cls, new])
94+
/// };
95+
/// // obj will be released when it goes out of scope
96+
///
97+
/// // share the object so we can clone it
98+
/// let obj: Id<_, Shared> = obj.into();
99+
/// let another_ref = obj.clone();
100+
/// // dropping our other reference will decrement the retain count
101+
/// drop(another_ref);
102+
///
103+
/// let weak = WeakId::new(&obj);
104+
/// assert!(weak.load().is_some());
105+
/// // After the object is deallocated, our weak pointer returns none
106+
/// drop(obj);
107+
/// assert!(weak.load().is_none());
108+
/// ```
109+
///
110+
/// ```no_run
87111
/// # use objc2::{class, msg_send};
88112
/// # use objc2::runtime::Object;
89-
/// # use objc2_id::{Id, Owned, Shared};
113+
/// # use objc2::rc::{Id, Owned, Shared};
90114
/// # type T = Object;
91115
/// let mut owned: Id<T, Owned>;
92116
/// # owned = unsafe { Id::new(msg_send![class!(NSObject), new]) };
@@ -145,7 +169,7 @@ impl<T: Message, O: Ownership> Id<T, O> {
145169
/// ```no_run
146170
/// # use objc2::{class, msg_send};
147171
/// # use objc2::runtime::{Class, Object};
148-
/// # use objc2_id::{Id, Owned};
172+
/// # use objc2::rc::{Id, Owned};
149173
/// let cls: &Class;
150174
/// # let cls = class!(NSObject);
151175
/// let obj: &mut Object = unsafe { msg_send![cls, alloc] };
@@ -157,7 +181,7 @@ impl<T: Message, O: Ownership> Id<T, O> {
157181
/// ```no_run
158182
/// # use objc2::{class, msg_send};
159183
/// # use objc2::runtime::Object;
160-
/// # use objc2_id::{Id, Shared};
184+
/// # use objc2::rc::{Id, Shared};
161185
/// # type NSString = Object;
162186
/// let cls = class!(NSString);
163187
/// // NSString is immutable, so don't create an owned reference to it
@@ -627,14 +651,8 @@ mod tests {
627651
use core::ptr::NonNull;
628652

629653
use super::{Id, Owned, ShareId, Shared, WeakId};
630-
use objc2::runtime::Object;
631-
use objc2::{class, msg_send};
632-
633-
#[cfg(not(target_vendor = "apple"))]
634-
#[test]
635-
fn ensure_linkage() {
636-
unsafe { crate::get_class_to_force_linkage() };
637-
}
654+
use crate::runtime::Object;
655+
use crate::{class, msg_send};
638656

639657
fn retain_count(obj: &Object) -> usize {
640658
unsafe { msg_send![obj, retainCount] }

objc2/src/rc/mod.rs

Lines changed: 61 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,70 @@
1-
/*!
2-
Utilities for reference counting Objective-C objects.
3-
4-
The utilities of the `rc` module provide ARC-like semantics for working with
5-
Objective-C's reference counted objects in Rust.
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-
See [the clang documentation][clang-arc] and [the Apple article on memory
14-
management][mem-mgmt] (similar document exists [for Core Foundation][mem-cf])
15-
for more information on automatic and manual reference counting.
16-
17-
It can also be useful to [enable Malloc Debugging][mem-debug] if you're trying
18-
to figure out if/where your application has memory errors and leaks.
19-
20-
21-
[clang-arc]: https://clang.llvm.org/docs/AutomaticReferenceCounting.html
22-
[mem-mgmt]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
23-
[mem-cf]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/CFMemoryMgmt.html
24-
[mem-debug]: https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html
25-
26-
# Example
27-
28-
``` no_run
29-
# use objc2::{class, msg_send};
30-
# use objc2::rc::{autoreleasepool, StrongPtr};
31-
// StrongPtr will release the object when dropped
32-
let obj = unsafe {
33-
StrongPtr::new(msg_send![class!(NSObject), new])
34-
};
35-
36-
// Cloning retains the object an additional time
37-
let cloned = obj.clone();
38-
autoreleasepool(|_| {
39-
// Autorelease consumes the StrongPtr, but won't
40-
// actually release until the end of an autoreleasepool
41-
cloned.autorelease();
42-
});
43-
44-
// Weak references won't retain the object
45-
let weak = obj.weak();
46-
drop(obj);
47-
assert!(weak.load().is_null());
48-
```
49-
*/
1+
//! Utilities for reference counting Objective-C objects.
2+
//!
3+
//! The utilities of the `rc` module provide ARC-like semantics for working
4+
//! with Objective-C's reference counted objects in Rust.
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.
16+
//!
17+
//! To enforce aliasing rules, an `Id` can be either owned or shared; if it is
18+
//! owned, meaning the `Id` is the only reference to the object, it can be
19+
//! mutably dereferenced. An owned `Id` can be downgraded to a shared `Id`
20+
//! which can be cloned to allow multiple references.
21+
//!
22+
//! Weak references may be created using the [`WeakId`] struct.
23+
//!
24+
//! See [the clang documentation][clang-arc] and [the Apple article on memory
25+
//! management][mem-mgmt] (similar document exists [for Core Foundation][mem-cf])
26+
//! for more information on automatic and manual reference counting.
27+
//!
28+
//! It can also be useful to [enable Malloc Debugging][mem-debug] if you're trying
29+
//! to figure out if/where your application has memory errors and leaks.
30+
//!
31+
//!
32+
//! [clang-arc]: https://clang.llvm.org/docs/AutomaticReferenceCounting.html
33+
//! [mem-mgmt]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
34+
//! [mem-cf]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/CFMemoryMgmt.html
35+
//! [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+
//! ```
5060
5161
mod autorelease;
62+
mod id;
5263
mod strong;
5364
mod weak;
5465

5566
pub use self::autorelease::{autoreleasepool, AutoreleasePool, AutoreleaseSafe};
67+
pub use self::id::{Id, Owned, Ownership, ShareId, Shared, WeakId};
5668
pub use self::strong::StrongPtr;
5769
pub use self::weak::WeakPtr;
5870

objc2_foundation/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,3 @@ block = ["objc2_block"]
2424
[dependencies]
2525
objc2_block = { path = "../objc2_block", optional = true }
2626
objc2 = { path = "../objc2" }
27-
objc2_id = { path = "../objc2_id" }

objc2_foundation/src/array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use core::marker::PhantomData;
55
use core::ops::{Index, Range};
66
use core::ptr::NonNull;
77

8+
use objc2::rc::{Id, Owned, Ownership, ShareId, Shared};
89
use objc2::runtime::{Class, Object};
910
use objc2::{class, msg_send};
1011
use objc2::{Encode, Encoding};
11-
use objc2_id::{Id, Owned, Ownership, ShareId, Shared};
1212

1313
use super::{INSCopying, INSFastEnumeration, INSMutableCopying, INSObject, NSEnumerator};
1414

@@ -415,7 +415,7 @@ mod tests {
415415

416416
use super::{INSArray, INSMutableArray, NSArray, NSMutableArray};
417417
use crate::{INSObject, INSString, NSObject, NSString};
418-
use objc2_id::Id;
418+
use objc2::rc::Id;
419419

420420
fn sample_array(len: usize) -> Id<NSArray<NSObject>> {
421421
let mut vec = Vec::with_capacity(len);

objc2_foundation/src/data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use core::{ffi::c_void, ptr::NonNull};
66

77
use super::{INSCopying, INSMutableCopying, INSObject, NSRange};
88
use objc2::msg_send;
9+
use objc2::rc::Id;
910
#[cfg(feature = "block")]
1011
use objc2_block::{Block, ConcreteBlock};
11-
use objc2_id::Id;
1212

1313
pub trait INSData: INSObject {
1414
fn len(&self) -> usize {

objc2_foundation/src/dictionary.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use core::marker::PhantomData;
44
use core::ops::Index;
55
use core::ptr::{self, NonNull};
66

7+
use objc2::rc::{Id, Owned, Ownership, ShareId};
78
use objc2::runtime::Class;
89
use objc2::{class, msg_send};
9-
use objc2_id::{Id, Owned, Ownership, ShareId};
1010

1111
use super::{INSCopying, INSFastEnumeration, INSObject, NSArray, NSEnumerator, NSSharedArray};
1212

@@ -166,7 +166,7 @@ where
166166
#[cfg(test)]
167167
mod tests {
168168
use alloc::vec;
169-
use objc2_id::Id;
169+
use objc2::rc::Id;
170170

171171
use super::{INSDictionary, NSDictionary};
172172
use crate::{INSArray, INSObject, INSString, NSObject, NSString};

objc2_foundation/src/enumerator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use core::ptr::NonNull;
55
use core::slice;
66
use std::os::raw::c_ulong;
77

8+
use objc2::rc::Id;
89
use objc2::runtime::Object;
910
use objc2::{msg_send, Encode, Encoding, RefEncode};
10-
use objc2_id::Id;
1111

1212
use super::INSObject;
1313

objc2_foundation/src/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use core::any::Any;
22
use core::ptr::NonNull;
33

44
use objc2::msg_send;
5+
use objc2::rc::{Id, ShareId};
56
use objc2::runtime::{Class, BOOL, NO};
67
use objc2::Message;
7-
use objc2_id::{Id, ShareId};
88

99
use super::NSString;
1010

0 commit comments

Comments
 (0)