@@ -7,6 +7,8 @@ use core::panic::{RefUnwindSafe, UnwindSafe};
7
7
use crate :: common:: * ;
8
8
use crate :: Foundation :: NSThread ;
9
9
10
+ use objc2:: msg_send_id;
11
+
10
12
unsafe impl Send for NSThread { }
11
13
unsafe impl Sync for NSThread { }
12
14
@@ -120,6 +122,43 @@ impl MainThreadMarker {
120
122
Self { _priv : PhantomData }
121
123
}
122
124
125
+ /// Allocate a new instance of the specified class on the main thread.
126
+ ///
127
+ /// This is essentially the same as [`ClassType::alloc`], the difference
128
+ /// being that it is also callable with classes that can only be used on
129
+ /// the main thread.
130
+ ///
131
+ ///
132
+ /// # Example
133
+ ///
134
+ /// Create an object on the main thread.
135
+ ///
136
+ /// ```
137
+ /// use icrate::Foundation::MainThreadMarker;
138
+ /// # use icrate::Foundation::NSObject as SomeClass;
139
+ /// # #[cfg(for_example)]
140
+ /// use icrate::SomeFramework::SomeClass;
141
+ /// use objc2::rc::Id;
142
+ /// use objc2::msg_send_id;
143
+ ///
144
+ /// # let mtm = unsafe { MainThreadMarker::new_unchecked() };
145
+ /// # #[cfg(doctests_not_always_run_on_main_thread)]
146
+ /// let mtm = MainThreadMarker::new().expect("must be on the main thread");
147
+ ///
148
+ /// // _All_ objects are safe to allocate on the main thread!
149
+ /// let obj = mtm.alloc::<SomeClass>();
150
+ ///
151
+ /// // Though more knowledge is required for safe initialization
152
+ /// let obj: Id<SomeClass> = unsafe { msg_send_id![obj, init] };
153
+ /// ```
154
+ #[ inline]
155
+ pub fn alloc < T : ClassType > ( self ) -> Option < Allocated < T > > {
156
+ // SAFETY: Same as `ClassType::alloc`, with the addition that since we
157
+ // take `self: MainThreadMarker`, the `IsAllocableAnyThread` bound is
158
+ // not required.
159
+ unsafe { msg_send_id ! [ T :: class( ) , alloc] }
160
+ }
161
+
123
162
/// Submit the given closure to the runloop on the main thread.
124
163
///
125
164
/// If the current thread is the main thread, this simply runs the
0 commit comments