1
1
#![ cfg_attr( not( all( feature = "apple" , target_os = "macos" ) ) , allow( unused) ) ]
2
- use objc2:: declare:: Ivar ;
3
- use objc2:: foundation:: NSObject ;
2
+ use objc2:: declare:: { Ivar , IvarDrop } ;
3
+ use objc2:: foundation:: { NSCopying , NSObject , NSString } ;
4
4
use objc2:: rc:: { Id , Shared } ;
5
5
use objc2:: runtime:: Object ;
6
- use objc2:: { declare_class, extern_class, msg_send, msg_send_id, ClassType } ;
6
+ use objc2:: { declare_class, extern_class, msg_send, msg_send_id, ns_string , ClassType } ;
7
7
8
8
#[ cfg( all( feature = "apple" , target_os = "macos" ) ) ]
9
9
#[ link( name = "AppKit" , kind = "framework" ) ]
@@ -23,6 +23,10 @@ declare_class!(
23
23
struct CustomAppDelegate {
24
24
pub ivar: u8 ,
25
25
another_ivar: bool ,
26
+ box_ivar: IvarDrop <Box <i32 >>,
27
+ maybe_box_ivar: IvarDrop <Option <Box <i32 >>>,
28
+ id_ivar: IvarDrop <Id <NSString , Shared >>,
29
+ maybe_id_ivar: IvarDrop <Option <Id <NSString , Shared >>>,
26
30
}
27
31
28
32
unsafe impl ClassType for CustomAppDelegate {
@@ -34,18 +38,28 @@ declare_class!(
34
38
#[ sel( initWith: another: ) ]
35
39
fn init_with( self : & mut Self , ivar: u8 , another_ivar: bool ) -> Option <& mut Self > {
36
40
let this: Option <& mut Self > = unsafe { msg_send![ super ( self ) , init] } ;
41
+
42
+ // TODO: `ns_string` can't be used inside closures; investigate!
43
+ let s = ns_string!( "def" ) ;
44
+
37
45
this. map( |this| {
46
+ // Initialize instance variables
47
+
48
+ // The explicit way to initialize an instance variable:
38
49
Ivar :: write( & mut this. ivar, ivar) ;
39
- Ivar :: write( & mut this. another_ivar, another_ivar) ;
40
- // Note that we could have done this with just:
41
- // *this.ivar = ivar;
42
- // *this.another_ivar = another_ivar;
43
- //
44
- // Since these two ivar types (`u8` and `bool`) are safe to
45
- // initialize from all zeroes; but for this example, we chose
46
- // to be explicit.
47
-
48
- // SAFETY: All the instance variables have been initialized
50
+ // For some types like `u8`, `bool`, `Option<Box<T>>` and
51
+ // `Option<Id<T, O>>` which are safe to zero-initialize, we
52
+ // can simply write to the variable as normal:
53
+ * this. another_ivar = another_ivar;
54
+ * this. maybe_box_ivar = None ;
55
+ * this. maybe_id_ivar = Some ( s. copy( ) ) ;
56
+ // While for others like `&u8`, `Box<T>` or `Id<T, O>`, we
57
+ // have to initialize it with `Ivar::write`:
58
+ Ivar :: write( & mut this. box_ivar, Box :: new( 2 ) ) ;
59
+ Ivar :: write( & mut this. id_ivar, NSString :: from_str( "abc" ) ) ;
60
+
61
+ // All the instance variables have been initialized; our
62
+ // initializer is sound
49
63
this
50
64
} )
51
65
}
@@ -97,8 +111,12 @@ impl CustomAppDelegate {
97
111
fn main ( ) {
98
112
let delegate = CustomAppDelegate :: new ( 42 , true ) ;
99
113
100
- println ! ( "{}" , delegate. ivar) ;
101
- println ! ( "{}" , delegate. another_ivar) ;
114
+ println ! ( "{:?}" , delegate. ivar) ;
115
+ println ! ( "{:?}" , delegate. another_ivar) ;
116
+ println ! ( "{:?}" , delegate. box_ivar) ;
117
+ println ! ( "{:?}" , delegate. maybe_box_ivar) ;
118
+ println ! ( "{:?}" , delegate. id_ivar) ;
119
+ println ! ( "{:?}" , delegate. maybe_id_ivar) ;
102
120
}
103
121
104
122
#[ cfg( not( all( feature = "apple" , target_os = "macos" ) ) ) ]
0 commit comments