custom_class/
custom_class.rs

1#[macro_use]
2extern crate objc;
3extern crate objc_foundation;
4
5use std::sync::{Once, ONCE_INIT};
6
7use objc::Message;
8use objc::declare::ClassDecl;
9use objc::runtime::{Class, Object, Sel};
10use objc_foundation::{INSObject, NSObject};
11
12pub enum MYObject { }
13
14impl MYObject {
15    fn number(&self) -> u32 {
16        unsafe {
17            let obj = &*(self as *const _ as *const Object);
18            *obj.get_ivar("_number")
19        }
20    }
21
22    fn set_number(&mut self, number: u32) {
23        unsafe {
24            let obj =  &mut *(self as *mut _ as *mut Object);
25            obj.set_ivar("_number", number);
26        }
27    }
28}
29
30unsafe impl Message for MYObject { }
31
32static MYOBJECT_REGISTER_CLASS: Once = ONCE_INIT;
33
34impl INSObject for MYObject {
35    fn class() -> &'static Class {
36        MYOBJECT_REGISTER_CLASS.call_once(|| {
37            let superclass = NSObject::class();
38            let mut decl = ClassDecl::new("MYObject", superclass).unwrap();
39            decl.add_ivar::<u32>("_number");
40
41            // Add ObjC methods for getting and setting the number
42            extern fn my_object_set_number(this: &mut Object, _cmd: Sel, number: u32) {
43                unsafe { this.set_ivar("_number", number); }
44            }
45
46            extern fn my_object_get_number(this: &Object, _cmd: Sel) -> u32 {
47                unsafe { *this.get_ivar("_number") }
48            }
49
50            unsafe {
51                let set_number: extern fn(&mut Object, Sel, u32) = my_object_set_number;
52                decl.add_method(sel!(setNumber:), set_number);
53                let get_number: extern fn(&Object, Sel) -> u32 = my_object_get_number;
54                decl.add_method(sel!(number), get_number);
55            }
56
57            decl.register();
58        });
59
60        Class::get("MYObject").unwrap()
61    }
62}
63
64fn main() {
65    let mut obj = MYObject::new();
66
67    obj.set_number(7);
68    println!("Number: {}", unsafe {
69        let number: u32 = msg_send![obj, number];
70        number
71    });
72
73    unsafe {
74        let _: () = msg_send![obj, setNumber:12u32];
75    }
76    println!("Number: {}", obj.number());
77}