Skip to content

Commit 35fb923

Browse files
committed
Add ClassBuilder::add_static_ivar
1 parent 8b9df64 commit 35fb923

File tree

5 files changed

+24
-9
lines changed

5 files changed

+24
-9
lines changed

objc2/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1414
(default) feature flag `"foundation"`.
1515
* Added `declare_class!`, `extern_class!` and `ns_string!` macros from
1616
`objc2-foundation`.
17+
* Added helper method `ClassBuilder::add_static_ivar`.
1718

1819
### Changed
1920
* **BREAKING**: Change selector syntax in `declare_class!` macro to be more Rust-like.

objc2/examples/class_with_lifetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'a> MyObject<'a> {
7171
let superclass = NSObject::class();
7272
let mut builder = ClassBuilder::new("MyObject", superclass).unwrap();
7373

74-
builder.add_ivar::<<NumberIvar<'a> as IvarType>::Type>(<NumberIvar<'a>>::NAME);
74+
builder.add_static_ivar::<NumberIvar<'a>>();
7575

7676
/// Helper struct since we can't access the instance variable
7777
/// from inside MyObject, since it hasn't been initialized yet!

objc2/src/declare.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,11 @@ impl ClassBuilder {
402402

403403
/// Adds an ivar with type `T` and the provided name.
404404
///
405+
///
405406
/// # Panics
406407
///
407-
/// If the ivar wasn't successfully added.
408+
/// If the ivar wasn't successfully added (for example, there already was
409+
/// an ivar with that name).
408410
pub fn add_ivar<T: Encode>(&mut self, name: &str) {
409411
let c_name = CString::new(name).unwrap();
410412
let encoding = CString::new(T::ENCODING.to_string()).unwrap();
@@ -422,6 +424,16 @@ impl ClassBuilder {
422424
assert!(success.as_bool(), "Failed to add ivar {}", name);
423425
}
424426

427+
/// Adds an instance variable from an [`IvarType`].
428+
///
429+
///
430+
/// # Panics
431+
///
432+
/// Same as [`ClassBuilder::add_ivar`].
433+
pub fn add_static_ivar<T: IvarType>(&mut self) {
434+
self.add_ivar::<T::Type>(T::NAME);
435+
}
436+
425437
/// Adds the given protocol to self.
426438
///
427439
/// # Panics

objc2/src/declare/ivar.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,14 @@ unsafe impl<T: IvarType> IvarType for MaybeUninit<T> {
7272
/// particular, this is never safe to have on the stack by itself.
7373
///
7474
/// Additionally, the instance variable described by `T` must be available on
75-
/// the specific instance, and be of the exact same type.
75+
/// the specific instance, and be of the exact same type. When declaring the
76+
/// object yourself, you can ensure this using
77+
/// [`ClassBuilder::add_static_ivar`].
7678
///
7779
/// Finally, two ivars with the same name must not be used on the same object.
7880
///
81+
/// [`ClassBuilder::add_static_ivar`]: crate::declare::ClassBuilder::add_static_ivar
82+
///
7983
///
8084
/// # Examples
8185
///
@@ -106,7 +110,7 @@ unsafe impl<T: IvarType> IvarType for MaybeUninit<T> {
106110
/// # use objc2::declare::ClassBuilder;
107111
/// # let mut builder = ClassBuilder::new("MyObject", class!(NSObject)).unwrap();
108112
/// // Declare the class and add the instance variable to it
109-
/// builder.add_ivar::<<MyCustomIvar as IvarType>::Type>(MyCustomIvar::NAME);
113+
/// builder.add_static_ivar::<MyCustomIvar>();
110114
/// # let _cls = builder.register();
111115
///
112116
/// let obj: MyObject;

objc2/src/macros/declare_class.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,7 @@ macro_rules! declare_class {
495495
unsafe $v struct $name<>: $inherits, $($inheritance_rest,)* $crate::runtime::Object {
496496
// SAFETY:
497497
// - The ivars are in a type used as an Objective-C object.
498-
// - The instance variable is defined in the exact same manner
499-
// in `class` below.
498+
// - The ivar is added to the class below.
500499
// - Rust prevents having two fields with the same name.
501500
// - Caller upholds that the ivars are properly initialized.
502501
$($ivar_v $ivar: $crate::declare::Ivar<$ivar>,)*
@@ -527,10 +526,9 @@ macro_rules! declare_class {
527526
);
528527
let mut builder = $crate::declare::ClassBuilder::new(stringify!($name), superclass).expect(err_str);
529528

529+
// Ivars
530530
$(
531-
builder.add_ivar::<<$ivar as $crate::declare::IvarType>::Type>(
532-
<$ivar as $crate::declare::IvarType>::NAME
533-
);
531+
builder.add_static_ivar::<$ivar>();
534532
)*
535533

536534
$(

0 commit comments

Comments
 (0)