Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/objc2/examples/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 3 kB image not shown  

Quelle  class_with_lifetime.rs

  Sprache: Rust
 

//! Note: We can't use the `define_class!` macro for this, it doesn't support
//! such use-cases (yet). Instead, we'll create it manually.
#![deny(unsafe_op_in_unsafe_fn)]
use std::cell::Cell;
use std::marker::PhantomData;
use std::sync::Once;

use objc2::rc::Retained;
use objc2::runtime::{AnyClass, AnyObject, ClassBuilder, NSObject};
use objc2::{msg_send, ClassType, Encoding, Message, RefEncode};

/// The type of the instance variable that we want to store
type Ivar<'a> = &'a Cell<u8>;

/// Struct that represents our custom object.
#[repr(C)]
struct MyObject<'a> {
    /// Required to give MyObject the proper layout
    ///
    /// Beware: `retain`-ing this field directly is dangerous, since it'd make
    /// it possible to extend the lifetime of the object beyond lifetime `'a`.
    inner: AnyObject,
    /// For auto traits and variance
    p: PhantomData<Ivar<'a>>,
}

unsafe impl RefEncode for MyObject<'_> {
    const ENCODING_REF: Encoding = NSObject::ENCODING_REF;
}

unsafe impl Message for MyObject<'_> {}

impl<'a> MyObject<'a> {
    fn class() -> &'static AnyClass {
        // NOTE: Use std::lazy::LazyCell if in MSRV
        static REGISTER_CLASS: Once = Once::new();

        REGISTER_CLASS.call_once(|| {
            let superclass = NSObject::class();
            let mut builder = ClassBuilder::new(c"MyObject", superclass).unwrap();

            builder.add_ivar::<Ivar<'_>>(c"number");

            let _cls = builder.register();
        });
        AnyClass::get(c"MyObject").unwrap()
    }

    fn new(number: &'a mut u8) -> Retained<Self> {
        // SAFETY: The instance variable is initialized below.
        let this: Retained<Self> = unsafe { msg_send![Self::class(), new] };

        // It is generally very hard to use `mut` in Objective-C, so let's use
        // interior mutability instead.
        let number = Cell::from_mut(number);

        let ivar = Self::class().instance_variable(c"number").unwrap();
        // SAFETY: The ivar is added with the same type below, and the
        // lifetime of the reference is properly bound to the class.
        unsafe { ivar.load_ptr::<Ivar<'_>>(&this.inner).write(number) };
        this
    }

    fn get(&self) -> u8 {
        let ivar = Self::class().instance_variable(c"number").unwrap();
        // SAFETY: The ivar is added with the same type below, and is initialized in `new`
        unsafe { ivar.load::<Ivar<'_>>(&self.inner).get() }
    }

    fn set(&self, number: u8) {
        let ivar = Self::class().instance_variable(c"number").unwrap();
        // SAFETY: The ivar is added with the same type below, and is initialized in `new`
        unsafe { ivar.load::<Ivar<'_>>(&self.inner).set(number) };
    }
}

fn main() {
    let mut number = 54;

    let obj = MyObject::new(&mut number);
    assert_eq!(obj.get(), 54);

    // We can now mutate the referenced `number`
    obj.set(7);
    assert_eq!(obj.get(), 7);

    // And we can clone the object, since we use interior mutability.
    let clone = obj.clone();
    clone.set(42);
    assert_eq!(obj.get(), 42);
    drop(clone);

    // It is not possible to convert to `Retained<NSObject>`, since that would
    // loose the lifetime information that `MyObject` stores.
    //
    // let obj = obj.into_super();
    //
    // Neither is it not possible to access `number` any more, since `obj`
    // holds a mutable reference to it.
    //
    // assert_eq!(number, 42);

    drop(obj);
    // And now that we've dropped `obj`, we can access `number` again
    assert_eq!(number, 42);
}

Messung V0.5 in Prozent
C=67 H=85 G=76

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.