@@ -72,10 +72,14 @@ unsafe impl<T: IvarType> IvarType for MaybeUninit<T> {
72
72
/// particular, this is never safe to have on the stack by itself.
73
73
///
74
74
/// 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`].
76
78
///
77
79
/// Finally, two ivars with the same name must not be used on the same object.
78
80
///
81
+ /// [`ClassBuilder::add_static_ivar`]: crate::declare::ClassBuilder::add_static_ivar
82
+ ///
79
83
///
80
84
/// # Examples
81
85
///
@@ -106,7 +110,7 @@ unsafe impl<T: IvarType> IvarType for MaybeUninit<T> {
106
110
/// # use objc2::declare::ClassBuilder;
107
111
/// # let mut builder = ClassBuilder::new("MyObject", class!(NSObject)).unwrap();
108
112
/// // 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>( );
110
114
/// # let _cls = builder.register();
111
115
///
112
116
/// let obj: MyObject;
@@ -123,11 +127,8 @@ pub struct Ivar<T: IvarType> {
123
127
item : PhantomData < T :: Type > ,
124
128
}
125
129
126
- impl < T : IvarType > Deref for Ivar < T > {
127
- type Target = T :: Type ;
128
-
129
- #[ inline]
130
- fn deref ( & self ) -> & Self :: Target {
130
+ impl < T : IvarType > Ivar < T > {
131
+ fn get_ref ( & self ) -> & T :: Type {
131
132
// SAFETY: The user ensures that this is placed in a struct that can
132
133
// be reinterpreted as an `Object`. Since `Ivar` can never be
133
134
// constructed by itself (and is neither Copy nor Clone), we know that
@@ -146,13 +147,10 @@ impl<T: IvarType> Deref for Ivar<T> {
146
147
// exists and has the correct type
147
148
unsafe { obj. ivar :: < T :: Type > ( T :: NAME ) }
148
149
}
149
- }
150
150
151
- impl < T : IvarType > DerefMut for Ivar < T > {
152
- #[ inline]
153
- fn deref_mut ( & mut self ) -> & mut Self :: Target {
151
+ fn get_mut_ptr ( & mut self ) -> * mut T :: Type {
154
152
let ptr = NonNull :: from ( self ) . cast :: < Object > ( ) ;
155
- // SAFETY: Same as `deref `.
153
+ // SAFETY: Same as `get_ref `.
156
154
//
157
155
// Note: We don't use `mut` because the user might have two mutable
158
156
// references to different ivars, as such:
@@ -177,12 +175,33 @@ impl<T: IvarType> DerefMut for Ivar<T> {
177
175
// this is definitely safe.
178
176
let obj = unsafe { ptr. as_ref ( ) } ;
179
177
180
- // SAFETY: Same as `deref`
181
- //
182
- // Safe as mutable because there is only one access to a particular
183
- // ivar at a time (since we have `&mut self`). `Object` is
178
+ // SAFETY: User ensures that the `Ivar<T>` is only used when the ivar
179
+ // exists and has the correct type
180
+ unsafe { obj. ivar_ptr :: < T :: Type > ( T :: NAME ) }
181
+ }
182
+
183
+ #[ inline]
184
+ fn get_mut ( & mut self ) -> & mut T :: Type {
185
+ // SAFETY: Safe as mutable because there is only one access to a
186
+ // particular ivar at a time (since we have `&mut self`). `Object` is
184
187
// `UnsafeCell`, so mutable access through `&Object` is allowed.
185
- unsafe { obj. ivar_ptr :: < T :: Type > ( T :: NAME ) . as_mut ( ) . unwrap_unchecked ( ) }
188
+ unsafe { self . get_mut_ptr ( ) . as_mut ( ) . unwrap_unchecked ( ) }
189
+ }
190
+ }
191
+
192
+ impl < T : IvarType > Deref for Ivar < T > {
193
+ type Target = T :: Type ;
194
+
195
+ #[ inline]
196
+ fn deref ( & self ) -> & Self :: Target {
197
+ self . get_ref ( )
198
+ }
199
+ }
200
+
201
+ impl < T : IvarType > DerefMut for Ivar < T > {
202
+ #[ inline]
203
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
204
+ self . get_mut ( )
186
205
}
187
206
}
188
207
0 commit comments