PackageTrack
Sign in Get early access

objc2

Objective-C interface and runtime bindings

0.6.4 100M downloads/mo #810 most downloaded on crates.io madsmtm/objc2

What this package is like to depend on

Last release 5 months ago

26 Feb 2026

Ships fairly regularly

a new release about every 3 months

Nearly every release is documented

notes for 11 of 11 stable releases

Nothing withdrawn

no release was ever pulled

5 years old

27 releases · first in 2021

2 releases in the last 12 months

see the full history below

Release timeline

27 releases · Nov 2021 to Feb 2026
2022 2023 2024 2025 2026
Release Pre-release

Releases

latest 27
  1. 0.6.4 26 Feb 2026
    Release notes

    Bump objc2 0.6.3 -> 0.6.4

    Open source →
    Release notes
    Open source →
  2. 0.6.3 04 Oct 2025
    Release notes

    Fix documentation on docs.rs

    Open source →
    Release notes
    Open source →
  3. 0.6.2 14 Aug 2025
    Release notes

    chore: Release objc2 version 0.6.2

    Open source →
    Release notes
    Open source →
  4. 0.6.1 19 Apr 2025
    Release notes

    chore: Release objc2 version 0.6.1

    Open source →
    Release notes
    Open source →
  5. 0.6.0 22 Jan 2025
    Release notes

    Added

    • Added AnyClass::is_metaclass.
    • Added MainThreadMarker from objc2-foundation.
      • MainThreadMarker::new_unchecked and MainThreadBound::new is now available in const. This is useful for creating main-thread only statics.
      • MainThreadMarker::from now debug-asserts that it is actually running on the main thread.
    • Added MainThreadOnly::mtm.
    • Added DowncastTarget, AnyObject::downcast_ref and Retained::downcast to allow safely casting between Objective-C objects.
    • Implemented more fmt traits on Retained.
    • Implemented Extend trait on Retained.
    • Implemented AsRef in a forwarding fashion on Retained.
    • Implemented PartialEq and PartialOrd on Retained in a slightly more generic way.
    • Allow using Into to convert to retained objects.
    • Make Retained::into_super an inherent method instead of an associated method. This means that you can now use it as .into_super().
    • Added the available!() macro for determining whether code is running on a given operating system.
    • Implement Message for AnyClass and AnyProtocol.
    • Allow AnyClass and AnyProtocol to be converted to AnyObject (both of these can act as objects).
    • Classes created using define_class! now implement Send and Sync when subclassing NSObject.
    • Added 16-fold Encode and RefEncode impls for function pointers (previously only implemented for up to 12 arguments, which turned out to be insufficient).
    • Added #[unsafe(method_family = ...)] attribute in extern_methods!, extern_protocol! and define_class!, to allow overriding the inferred method family if need be.
    • Added PartialEq, Eq, Hash, PartialOrd and Ord implementations for Bool.
    • Added "disable-encoding-assertions" Cargo feature flag to allow completely disabling encoding verification.

    Changed

    • BREAKING: Renamed declare_class! to define_class!, and changed the syntax to be more succinct:

      // Before
      use objc2::mutability::InteriorMutable;
      use objc2::runtime::{NSObject, NSObjectProtocol};
      use objc2::{declare_class, ClassType, DeclaredClass};
      
      struct MyIvars;
      
      declare_class!(
          struct MyObject;
      
          unsafe impl ClassType for MyObject {
              type Super = NSObject;
              type Mutability = InteriorMutable;
              const NAME: &'static str = "MyObject";
          }
      
          impl DeclaredClass for MyObject {
              type Ivars = MyIvars;
          }
      
          unsafe impl MyObject {
              #[method(myMethod)]
              fn my_method(&self) {
                  // ...
              }
          }
      
          unsafe impl NSObjectProtocol for MyObject {}
      );
      
      // After
      use objc2::runtime::{NSObject, NSObjectProtocol};
      use objc2::define_class;
      
      struct MyIvars;
      
      define_class!(
          #[unsafe(super(NSObject))]
          #[name = "MyObject"]
          #[ivars = MyIvars]
          struct MyObject;
      
          impl MyObject {
              #[unsafe(method(myMethod))]
              fn my_method(&self) {
                  // ...
              }
          }
      
          unsafe impl NSObjectProtocol for MyObject {}
      );
      
    • Whether classes are only available on the main thread is now automatically inferred, and you only need to overwrite it if your class is doing something different than its superclass.

    • BREAKING: Changed the syntax of extern_class! to be more succinct:

      // Before
      use objc2::mutability::MainThreadOnly;
      use objc2::runtime::NSObject;
      use objc2::{extern_class, ClassType};
      
      extern_class!(
          #[derive(PartialEq, Eq, Hash, Debug)]
          struct MyClass;
      
          unsafe impl ClassType for MyClass {
              type Super = NSObject;
              type ThreadKind = dyn MainThreadOnly;
              const NAME: &'static str = "MyClass";
          }
      );
      
      // After
      use objc2::runtime::NSObject;
      use objc2::{extern_class, MainThreadOnly};
      
      extern_class!(
          #[unsafe(super(NSObject))]
          #[thread_kind = MainThreadOnly]
          #[name = "MyClass"]
          #[derive(PartialEq, Eq, Hash, Debug)]
          struct MyClass;
      );
      
    • BREAKING: Changed the syntax of extern_protocol! to be more succinct:

      // Before
      extern_protocol!(
          unsafe trait MyProtocol {
              #[method(myMethod)]
              fn myMethod(&self);
          }
      
          // The line below is now unnecessary
          unsafe impl ProtocolType for dyn MyProtocol {}
      );
      
      // After
      extern_protocol!(
          unsafe trait MyProtocol {
              #[unsafe(method(myMethod))]
              fn myMethod(&self);
          }
      );
      
    • BREAKING: Changed the syntax of extern_methods! to push the unsafe inside:

      // Before
      extern_methods!(
          unsafe impl MyObject {
              #[method(myMethod)]
              fn myMethod(&self);
          }
      );
      
      // After
      impl MyObject {
          extern_methods!(
              #[unsafe(method(myMethod))]
              fn myMethod(&self);
          );
      }
      
    • BREAKING: Moved the common retain and alloc methods from ClassType to Message and AllocAnyThread/MainThreadOnly, respectively.

      // Before
      use objc2::ClassType;
      let my_obj = MyObject::init(MyObject::alloc());
      let retained = my_obj.retain();
      
      // After
      use objc2::{Message, AllocAnyThread}; // Need different trait imports
      let my_obj = MyObject::init(MyObject::alloc());
      let retained = my_obj.retain();
      
    • Print backtrace when catching exceptions with the "catch-all" feature.

    • Changed the return value of ClassBuilder::add_protocol to indicate whether the protocol was already present on the class or not.

    • Merged objc-sys into this crate's ffi module.

    • BREAKING: Changed the signature of various ffi functions to no longer accept nullable function pointers.

    • BREAKING: Changed the signature of various ffi functions to use the proper Bool type instead of a typedef.

    • Made exception::catch safe.

    Deprecated

    • Merged and deprecated the following ffi types:

      • ffi::objc_class is merged into runtime::AnyClass.
      • ffi::objc_object is merged into runtime::AnyObject.
      • ffi::objc_protocol is merged into runtime::AnyProtocol.
      • ffi::IMP is merged into runtime::Imp.
      • ffi::objc_method is merged into runtime::Method.
      • ffi::objc_ivar is merged into runtime::Ivar.
      • ffi::BOOL and constants is merged into runtime::Bool.
    • Deprecated ffi::id. Use AnyObject instead.

    • Deprecated NSObjectProtocol::is_kind_of, use isKindOfClass or the new AnyObject::downcast_ref method instead.

    • Deprecated Retained::cast, this has been renamed to Retained::cast_unchecked.

    • Renamed DeclaredClass to DefinedClass.

    • Merged msg_send! and msg_send_id!. The latter is now deprecated.

    • Merged #[method(...)] and #[method_id(...)] in extern_methods! and extern_protocol!. #[method_id(...)] is now deprecated.

    • Deprecated rc::Weak::from_id. Use rc::Weak::from_retained instead.

    • Deprecated ProtocolObject::from_id. Use ProtocolObject::from_retained instead.

    • Deprecated using msg_send! without a comma between arguments.

      See the following for an example of how to upgrade:

      // Before
      let _: NSInteger = msg_send![
          obj,
          addTrackingRect:rect
          owner:obj
          userData:ptr::null_mut::<c_void>()
          assumeInside:Bool::NO
      ];
      // After
      let _: NSInteger = msg_send![
          obj,
          addTrackingRect: rect, // Added comma
          owner: obj, // Added comma
          userData: ptr::null_mut::<c_void>(), // Added comma
          assumeInside: false, // Added comma (optional when trailing)
      ];
      

    Removed

    • BREAKING: Removed the ffi::SEL and ffi::objc_selector types. Use runtime::Sel instead.
    • BREAKING: Removed ffi exception function pointer aliases.
    • BREAKING: Removed mutability::HasStableHash.
    • BREAKING: Removed various _mut methods:
      • Retained::as_mut_ptr.
      • Retained::autorelease_mut.
      • DeclaredClass::ivars_mut.
      • ProtocolObject::from_mut.
      • AutoreleasePool::ptr_as_mut.
      • ClassType::as_super_mut.
    • BREAKING: Disallow &mut message receivers (except in the special case when the object is AnyObject, for better backwards compatibility with objc).
    • BREAKING: Removed AsMut, BorrowMut and DerefMut implementations in extern_class! and declare_class!.
    • BREAKING: Removed the mutability module, and everything within. Classes now always use interior mutability.
    • BREAKING: Removed DerefMut implementation for Retained<T> when the Retained was mutable.
    • BREAKING: Mark Retained::autorelease as unsafe, since we cannot ensure that the given pool is actually the innermost pool.
    • BREAKING: Removed the deprecated malloc feature and malloc_buf dependency.
    • BREAKING: Removed aliases DefaultId, IdFromIterator and IdIntoIterator, as well as their methods. Use the renamed traits instead.
    • BREAKING: Removed the ability to implement ClassType manually, to make it easier to evolve the API going forwards.
    • BREAKING: Removed the deprecated apple Cargo feature flag.
    • The optimization for converting msg_send_id![cls, alloc] to a call to the faster runtime function objc_alloc no longer works, use AllocAnyThread::alloc or MainThreadOnly::alloc instead.

    Fixed

    • Remove an incorrect assertion when adding protocols to classes in an unexpected order.

    • BREAKING: Converted function signatures into using extern "C-unwind" where applicable. This allows Rust and Objective-C unwinding to interoperate.

    • BREAKING: Use CStr in methods in the runtime module, since it's both more performant, and more correct. Use the new c"my_str" syntax to migrate.

      Specifically, this includes:

      • ClassBuilder::new.
      • ClassBuilder::root.
      • ClassBuilder::add_ivar.
      • ProtocolBuilder::new.
      • Sel::register.
      • Sel::name.
      • Ivar::name.
      • Ivar::type_encoding.
      • Method::return_type.
      • Method::argument_type.
      • AnyClass::get.
      • AnyClass::name.
      • AnyClass::instance_variable.
      • AnyProtocol::get.
      • AnyProtocol::name.
    • Clarified that exception::catch does not catch Rust panics.

    • Improved the Debug impl when deriving via extern_class!.

    • Generic objects now always implement common traits PartialEq, Eq and Hash, instead of guarding them behind T: Message.

    • Prevented main thread only classes created using declare_class! from automatically implementing the auto traits Send and Sync.

    • BREAKING: Fixed the signature of NSObjectProtocol::isEqual to take a nullable argument.

    • Fixed handling of methods that return NULL errors. This affected for example -[MTLBinaryArchive serializeToURL:error:].

    • Fixed unwinding while using writeback / error parameters.

    Open source →
  6. 0.5.2 21 May 2024
    Release notes

    Added

    • Added Retained::autorelease_ptr.
    • Added the feature flag "relax-sign-encoding", which when enabled, allows using e.g. NSInteger in places where you would otherwise have to use NSUInteger.

    Changed

    • Renamed Id to Retained, to better reflect what it represents.

      The old name is kept as a soft-deprecated type-alias (will be fully deprecated in v0.6.0).

      The same is done for:

      • rc::WeakId to rc::Weak.
      • rc::DefaultId to rc::DefaultRetained.
      • rc::IdFromIterator to rc::RetainedFromIterator.
      • rc::IdIntoIterator to rc::RetainedIntoIterator.

    Deprecated

    • Deprecated the apple Cargo feature flag, it is assumed by default on Apple platforms.
    Open source →
  7. 0.5.1 17 Apr 2024
    Release notes

    Added

    • Made the following runtime methods available without the "malloc" feature flag:
      • Method::return_type.
      • Method::argument_type.
      • AnyClass::classes.
      • AnyClass::instance_methods.
      • AnyClass::adopted_protocols.
      • AnyClass::instance_variables.
      • AnyProtocol::protocols.
      • AnyProtocol::adopted_protocols.
    • Added Id::into_raw as the oppositve of Id::from_raw.
    • Added the following missing methods on NSObjectProtocol:
      • isEqual.
      • hash.
      • isKindOfClass.
      • isMemberOfClass.
      • respondsToSelector.
      • conformsToProtocol.
      • description.
      • debugDescription.
      • isProxy.
      • retainCount.
    • Added NSObject::init.
    • Added NSObject::doesNotRecognizeSelector.

    Changed

    • Moved ClassBuilder and ProtocolBuilder from the declare module to the runtime module. The old locations are deprecated.
    • Enabled the "verify" feature flag's functionality when debug assertions are enabled.
    • Renamed Id::new to Id::from_raw. The previous name is kept as a deprecated alias.
    Open source →
  8. 0.5.0 03 Dec 2023
    Release notes

    Added

    • Added the following traits to the mutability module (see the documentation for motivation and usage info):
      • HasStableHash.
      • IsAllowedMutable.
      • IsMainThreadOnly.
      • CounterpartOrSelf.
    • Added new encode traits EncodeReturn, EncodeArgument and EncodeArguments.
    • Added methods as_ptr and as_mut_ptr to Allocated.
    • Added optimization for converting msg_send_id![cls, alloc] to a call to the faster runtime function objc_alloc.
    • Added DeclaredClass, which represents classes that are declared in Rust.
    • Added Allocated::set_ivars, which sets the instance variables of an object, and returns the new rc::PartialInit.
    • Added the ability for msg_send_id! to call super methods.
    • Implement Send and Sync for ProtocolObject if the underlying protocol implements it.
    • Added ability to create Send and Sync versions of ProtocolObject<dyn NSObjectProtocol>.

    Changed

    • BREAKING: Changed how instance variables work in declare_class!.

      Previously, instance variables had to implement Encode, and you had to initialize them properly, which was difficult to ensure.

      Now, you implement the new DeclaredClass trait instead, which helps to ensure all of this for you.

      // Before
      declare_class!(
          struct MyObject {
              object: IvarDrop<Id<NSObject>, "_object">,
              data: IvarDrop<Option<Box<MyData>>, "_data">,
          }
      
          mod ivars;
      
          unsafe impl ClassType for MyObject {
              type Super = NSObject;
              type Mutability = InteriorMutable;
              const NAME: &'static str = "MyObject";
          }
      
          unsafe impl MyObject {
              #[method(init)]
              unsafe fn init(this: *mut Self) -> Option<NonNull<Self>> {
                  let this: Option<&mut Self> = msg_send![super(this), init];
                  this.map(|this| {
                      Ivar::write(&mut this.object, NSObject::new());
                      Ivar::write(&mut this.data, Box::new(MyData::new()));
                      NonNull::from(this)
                  })
              }
          }
      );
      
      extern_methods!(
          unsafe impl MyObject {
              #[method_id(new)]
              pub fn new() -> Id<Self>;
          }
      );
      
      fn main() {
          let obj = MyObject::new();
          println!("{:?}", obj.object);
      }
      
      // After
      struct MyIvars {
          object: Id<NSObject>,
          data: Option<Box<MyData>>,
      }
      
      declare_class!(
          struct MyObject;
      
          unsafe impl ClassType for MyObject {
              type Super = NSObject;
              type Mutability = InteriorMutable;
              const NAME: &'static str = "MyObject";
          }
      
          impl DeclaredClass for MyObject {
              type Ivars = MyIvars;
          }
      
          unsafe impl MyObject {
              #[method_id(init)]
              pub fn init(this: Allocated<Self>) -> Option<Id<Self>> {
                  let this = this.set_ivars(MyIvars {
                      object: NSObject::new(),
                      data: MyData::new(),
                  });
                  unsafe { msg_send_id![super(this), init] }
              }
          }
      );
      
      extern_methods!(
          unsafe impl MyObject {
              #[method_id(new)]
              pub fn new() -> Id<Self>;
          }
      );
      
      fn main() {
          let obj = MyObject::new();
          println!("{:?}", obj.ivars().object);
      }
      
    • BREAKING: AnyClass::verify_sel now take more well-defined types EncodeArguments and EncodeReturn.

    • BREAKING: Changed how the mutability traits work; these no longer have ClassType as a super trait, allowing them to work for ProtocolObject as well.

      This effectively means you can now copy a ProtocolObject<dyn NSCopying>.

    • BREAKING: Allow implementing DefaultId for any type, not just those who are IsAllocableAnyThread.

    • BREAKING: Moved the MethodImplementation trait from the declare module to the runtime module.

    • BREAKING: Moved the MessageReceiver trait to the runtime module.

    • BREAKING: Make the MessageReceiver trait no longer implemented for references to Id. Dereference the Id yourself.

      Note: Passing &Id in msg_send! is still supported.

    • BREAKING: MessageReceiver::send_message and MessageReceiver::send_super_message now take EncodeArguments and return EncodeReturn, instead of internal traits.

      This is done to make MessageReceiver more straightforward to understand, although it now also has slightly less functionality than msg_send!.

      In particular automatic conversion of bool is not supported in MessageReceiver.

    • Relaxed the requirements for receivers in MethodImplementation; now, anything that implements MessageReceiver can be used as the receiver of a method.

    • BREAKING: Renamed the associated types Ret and Args on MethodImplementation to Return and Arguments.

    • BREAKING: Make rc::Allocated allowed to be NULL internally, such that uses of Option<Allocated<T>> is now simply Allocated<T>.

    • AnyObject::class now returns a 'static reference to the class.

    • Relaxed ProtocolType requirement on ProtocolObject.

    • BREAKING: Updated encode types to those from objc2-encode v4.0.0.

    Fixed

    • Fixed the name of the protocol that NSObjectProtocol references.

    • Allow cloning Id<AnyObject>.

    • BREAKING: Restrict message sending to &mut references to things that implement IsAllowedMutable.

    • Disallow the ability to use non-Self-like types as the receiver in declare_class!.

    • Allow adding instance variables with the same name on Apple platforms.

    • BREAKING: Make loading instance variables robust and sound in the face of instance variables with the same name.

      To read or write the instance variable for an object, you should now use the load, load_ptr and load_mut methods on Ivar, instead of the ivar, ivar_ptr and ivar_mut methods on AnyObject.

      This is more verbose, but it also ensures that the class for the instance variable you're loading is the same as the one the instance variable you want to access is defined on.

      // Before
      let number = unsafe { *obj.ivar::<u32>("number") };
      
      // After
      let ivar = cls.instance_variable("number").unwrap();
      let number = unsafe { *ivar.load::<u32>(&obj) };
      
    • Implement RefEncode normally for c_void. This makes AtomicPtr<c_void> implement Encode.

    Removed

    • BREAKING: Removed ProtocolType implementation for NSObject. Use the more precise NSObjectProtocol trait instead!

    • BREAKING: Removed the MessageArguments trait.

    • BREAKING: Removed the following items from the declare module: Ivar, IvarEncode, IvarBool, IvarDrop, IvarType and InnerIvarType.

      Ivar functionality is available in a different form now, see above under "Changed".

    • BREAKING: Removed ClassBuilder::add_static_ivar.

    Open source →
  9. 0.4.1 31 Jul 2023
    Release notes

    Added

    • Allow using MainThreadMarker in extern_methods!.
    • Added the feature flag "relax-void-encoding", which when enabled, allows using *mut c_void in a few places where you would otherwise have to specify the encoding precisely.

    Changed

    • Renamed runtime types:

      • Object to AnyObject.
      • Class to AnyClass.
      • Protocol to AnyProtocol.

      To better fit with Swift's naming scheme. The types are still available under the old names as deprecated aliases.

    Fixed

    • BREAKING: Updated encode types to those from objc2-encode v3.0.0.

      This is technically a breaking change, but it should allow this crate to be compiled together with pre-release versions of it, meaning that in practice strictly more code out there will compile because of this. Hence it was deemed the better trade-off.

    Open source →
  10. 0.4.0 20 Jun 2023
    Release notes

    Added

    • Added objc2::rc::autoreleasepool_leaking, and improve performance of objects Debug impls.

    • BREAKING: Added associated type ClassType::Mutability, which replaces the ownership type on Id, and must be specified for all class types.

      An example:

      // Before
      use objc2::runtime::NSObject;
      use objc2::{declare_class, ClassType};
      
      declare_class!(
          struct MyDelegate;
      
          unsafe impl ClassType for MyDelegate {
              type Super = NSObject;
          }
      
          // ... methods
      );
      
      // After
      use objc2::runtime::NSObject;
      use objc2::mutability::InteriorMutable;
      use objc2::{declare_class, ClassType};
      
      declare_class!(
          struct MyDelegate;
      
          unsafe impl ClassType for MyDelegate {
              type Super = NSObject;
              type Mutability = InteriorMutable; // Added
          }
      
          // ... methods
      );
      
    • Added ClassType::retain, which is a safe way to go from a reference &T to an Id<T>.

    • Added mutability module, containing various types that can be specified for the above.

    • Preliminary support for specifying where bounds on methods inside extern_protocol! and extern_methods!.

    • Allow arbitrary expressions in const NAME in extern_class!, extern_protocol! and declare_class!.

    • Added rc::IdIntoIterator helper trait and forwarding IntoIterator implementations for rc::Id.

    • Added rc::IdFromIterator helper trait for implementing IntoIterator for rc::Id.

    • Added Display impl for runtime::Class, runtime::Sel and runtime::Protocol.

    • Added Debug impl for runtime::Method and runtime::Ivar.

    • Added Method::set_implementation.

    • Added Method::exchange_implementation.

    • Added Object::set_class.

    Changed

    • BREAKING: objc2::rc::AutoreleasePool is now a zero-sized Copy type with a lifetime parameter, instead of the lifetime parameter being the reference it was behind.

    • BREAKING: Made Id::autorelease and Id::autorelease_return be associated functions instead of methods. This means they now have to be called as Id::autorelease(obj, pool) instead of obj.autorelease(pool).

      Additionally, rename the mutable version to Id::autorelease_mut.

    • BREAKING: Moved VerificationError, ProtocolObject and ImplementedBy into the runtime module.

    • Relaxed a fmt::Debug bound on WeakId's own fmt::Debug impl.

    • Changed Debug impl for runtime::Class, runtime::Sel and runtime::Protocol to give more information.

    • BREAKING: Updated encode module to objc2-encode v2.0.0.

    Fixed

    • Fixed using autorelease pools on 32bit macOS and older macOS versions.
    • Fixed memory leaks in and improved performance of exception::catch.

    Removed

    • BREAKING: Removed rc::SliceId, since it is implementable outside objc2 from the layout guarantees of rc::Id.

    • BREAKING: Removed Ownership type parameter from Id, as well as rc::Ownership, rc::Owned, rc::Shared, Id::from_shared and Id::into_shared. This functionality has been moved from being at the "usage-level", to being moved to the "type-level" in the associated type ClassType::Mutability.

      While being slightly more restrictive, it should vastly help you avoid making mistakes around mutability (e.g. it is usually a mistake to make a mutable reference &mut to an Objective-C object).

      An example:

      // Before
      use objc2::rc::{Id, Shared};
      use objc2::runtime::NSObject;
      use objc2::msg_send_id;
      
      let obj: Id<NSObject, Shared> = unsafe { msg_send_id![NSObject::class(), new] };
      
      // After
      use objc2::rc::Id;
      use objc2::runtime::NSObject;
      use objc2::msg_send_id;
      
      let obj: Id<NSObject> = unsafe { msg_send_id![NSObject::class(), new] };
      
    • BREAKING: Removed impl<T> TryFrom<WeakId<T>> for Id<T> impl since it did not have a proper error type, making it less useful than WeakId::load.

    • BREAKING: Removed forwarding Iterator implementation for Id, since it conflicts with the IntoIterator implementation that it now has instead.

    Open source →
  11. 0.3.0-beta.5 07 Feb 2023 pre-release
    Release notes

    Added

    • Support #[cfg(...)] attributes in extern_class! macro.

    • Added support for selectors with multiple colons like abc:: in the sel!, extern_class!, extern_protocol! and declare_class! macros.

    • Added ability to use #[method_id(mySelector:)] inside declare_class!, like you would do in extern_methods!.

    • Added 16-fold impls for EncodeArguments, MessageArguments, and MethodImplementation.

    • Added NSObjectProtocol trait for allowing ProtocolObject to implement Debug, Hash, PartialEq and Eq.

    • Support running Drop impls on dealloc in declare_class!.

    • Added declare::IvarEncode and declare::IvarBool types.

    • BREAKING: Moved the objc2_encode traits to objc2::encode.

      This includes removing the EncodeConvert and EncodeArguments traits.

    • Added support for out-parameters like &mut Id<_, _> in msg_send!, msg_send_id! and extern_methods!.

    Changed

    • BREAKING: Using the automatic NSError**-to-Result functionality in extern_methods! now requires a trailing underscore (so now it's #[method(myMethod:error:_)] instead of #[method(myMethod:error:)]).

    • BREAKING: Fundamentally changed how protocols work. Instead of being structs with inherent methods, they're now traits. This means that you can use their methods more naturally from your Objective-C objects.

      An example:

      // Before
      extern_protocol!(
          struct MyProtocol;
      
          unsafe impl ProtocolType for MyProtocol {
              #[method(myMethod)]
              fn myMethod(&self);
          }
      );
      
      let obj: &SomeObjectThatImplementsTheProtocol = ...;
      let proto: &MyProtocol = obj.as_protocol();
      proto.myMethod();
      
      // After
      extern_protocol!(
          unsafe trait MyProtocol {
              #[method(myMethod)]
              fn myMethod(&self);
          }
      
          unsafe impl ProtocolType for dyn MyProtocol {}
      );
      
      let obj: &SomeObjectThatImplementsTheProtocol = ...;
      obj.myMethod();
      // Or
      let proto: &ProtocolObject<dyn MyProtocol> = ProtocolObject::from_ref(obj);
      proto.myMethod();
      

      The ConformsTo trait has similarly been removed, and the ImplementedBy trait and ProtocolObject struct has been introduced instead.

    • BREAKING: Moved NSObject::is_kind_of to the new NSObjectProtocol.

    • BREAKING: Removed support for custom dealloc impls in declare_class!. Implement Drop for the type instead.

    • BREAKING: Changed how the declare_class! macro works.

      Now, you must explicitly specify the "kind" of ivar you want, as well as the ivar name. Additionally, the class name must be explicitly specified.

      This change is done to make it easier to see what's going on beneath the hood (the name will be available in the final binary, which is important to be aware of)!

      An example:

      // Before
      declare_class!(
          struct MyClass {
              pub ivar: u8,
              another_ivar: bool,
              box_ivar: IvarDrop<Box<i32>>,
          }
      
          unsafe impl ClassType for MyClass {
              type Super = NSObject;
          }
      );
      
      // After
      declare_class!(
          struct MyClass {
              pub ivar: IvarEncode<u8, "_ivar">,
              another_ivar: IvarBool<"_another_ivar">,
              box_ivar: IvarDrop<Box<i32>, "_box_ivar">,
          }
      
          // Helper types for ivars will be put in here
          mod ivars;
      
          unsafe impl ClassType for MyClass {
              type Super = NSObject;
              const NAME: &'static str = "MyClass";
          }
      );
      
      
    • Updated ffi module to objc-sys v0.3.0. This includes:

      • Added free method (same as libc::free).
      • Moved documentation from README.md to docs.rs.
      • Added objc_terminate, object_isClass, objc_alloc and objc_allocWithZone now that Rust's macOS deployment target is 10.12.
      • Slightly improved documentation.
      • Internal optimizations.
      • BREAKING: Changed links key from objc_0_2 to objc_0_3 (so DEP_OBJC_0_2_CC_ARGS in build scripts becomes DEP_OBJC_0_3_CC_ARGS).
      • BREAKING: Renamed rust_objc_sys_0_2_try_catch_exception to try_catch.
      • Deprecated the unstable function try_catch, it is exposed in objc2-exception-helper instead.
    • BREAKING: Updated encode module to objc2-encode v2.0.0-pre.4.

    Fixed

    • Allow empty structs in declare_class! macro.
    • Allow using extern_methods! without the ClassType trait in scope.
    • Fixed a few small issues with declare_class!.
    • Fixed () being possible in argument position in msg_send!.
    Open source →
  12. 0.3.0-beta.4 24 Dec 2022 pre-release
    Release notes

    Added

    • Allow directly specifying class name in extern_class! macro.

    • Added ClassType::alloc.

      This means you can now simplify your code as follows:

      // Before
      let obj: Id<NSObject, Shared> = unsafe {
          msg_send_id![msg_send_id![NSObject::class(), alloc], init]
      };
      
      // After
      let obj: Id<NSObject, Shared> = unsafe {
          msg_send_id![NSObject::alloc(), init]
      };
      
    • Added Class::class_method.

    • Added the ability to specify error: _, somethingReturningError: _ and so on at the end of msg_send!/msg_send_id!, and have it automatically return a Result<..., Id<NSError, Shared>>.

    • Added the ability to specify an extra parameter at the end of the selector in methods declared with extern_methods!, and let that be the NSError** parameter.

    • Added #[method_id(...)] attribute to extern_methods!.

    • Added "verify" feature as a replacement for the "verify_message" feature.

    • Added extern_protocol! macro and ProtocolType trait.

    • Added ConformsTo trait for marking that a type conforms to a specific protocol.

    • Added Encode impl for Option<Sel>.

    • Added objc2::runtime::NSObject - before, this was only available under objc2::foundation::NSObject.

    • Added objc2::runtime::NSZone - before, this was only available under objc2::foundation::NSZone.

    Changed

    • Allow other types than &Class as the receiver in msg_send_id! methods of the new family.
    • BREAKING: Changed the Allocated struct to be used as Allocated<T> instead of Id<Allocated<T>, O>.
    • Verify the message signature of overridden methods when declaring classes if the verify feature is enabled.
    • Verify in declare_class! that protocols are implemented correctly.
    • BREAKING: Changed the name of the attribute macro in extern_methods from #[sel(...)] to #[method(...)].
    • BREAKING: Changed extern_methods! and declare_class! such that associated functions whose first parameter is called this, is treated as instance methods instead of class methods.
    • BREAKING: Message verification is now enabled by default. Your message sends might panic with debug_assertions enabled if they are detected to be invalid. Test your code to see if that is the case!
    • BREAKING: declare_class! uses ConformsTo<...> instead of the temporary Protocol<...> syntax.
    • Require implementors of Message to support weak references.
    • BREAKING: Moved objc2::foundation into icrate::Foundation.
    • BREAKING: Moved objc2::ns_string into icrate::ns_string.
    • Updated ffi module to objc-sys v0.2.0-beta.3. This includes:
      • Fixed minimum deployment target on macOS Aarch64.
    • BREAKING: Updated encode module objc2-encode v2.0.0-pre.3.

    Fixed

    • Fixed duplicate selector extraction in extern_methods!.
    • Fixed using deprecated attributes in declare_class!.
    • Fixed cfg attributes on methods and implementations in declare_class!.

    Removed

    • BREAKING: Removed "verify_message" feature. It has been mostly replaced by debug_assertions and the "verify" feature.
    Open source →
  13. 0.3.0-beta.3.patch-leaks.3 02 Apr 2023 pre-release

    Nothing published for this version

  14. 0.3.0-beta.3.patch-leaks.2 14 Mar 2023 pre-release

    Nothing published for this version

  15. 0.3.0-beta.3.patch-leaks 13 Mar 2023 pre-release

    Nothing published for this version

  16. 0.3.0-beta.3 01 Sep 2022 pre-release
    Release notes

    Added

    • Added Ivar::write, Ivar::as_ptr and Ivar::as_mut_ptr for safely querying and modifying instance variables inside init methods.
    • Added IvarDrop<T> to allow storing complex Drop values in ivars (currently rc::Id<T, O>, Box<T>, Option<rc::Id<T, O>> or Option<Box<T>>).
    • BREAKING: Added required ClassType::NAME constant for statically determining the name of a specific class.
    • Allow directly specifying class name in declare_class! macro.

    Removed

    • BREAKING: MaybeUninit no longer implements IvarType directly; use Ivar::write instead.
    Open source →
  17. 0.3.0-beta.2 28 Aug 2022 pre-release
    Release notes

    Added

    • Added the "unstable-static-class" and "unstable-static-class-inlined" feature flags to make the class! macro zero cost.

    • Moved the external crate objc2_foundation into objc2::foundation under (default) feature flag "foundation".

    • Added declare_class!, extern_class! and ns_string! macros from objc2-foundation.

    • Added helper method ClassBuilder::add_static_ivar.

    • BREAKING: Added ClassType trait, and moved the associated class methods that extern_class! and declare_class! generated to that. This means you'll have to use objc2::ClassType whenever you want to use e.g. NSData::class().

    • Added Id::into_super.

    • Added extern_methods! macro.

    • Added ability to call msg_send![super(obj), ...] without explicitly specifying the superclass.

    • Added automatic conversion of bool to/from the Objective-C BOOL in msg_send!, msg_send_id!, extern_methods! and declare_class!.

      Example:

      // Before
      use objc2::{msg_send, msg_send_bool};
      use objc2::rc::{Id, Shared};
      use objc2::runtime::{Bool, Object};
      
      let obj: Id<Object, Shared>;
      let _: () = unsafe { msg_send![&obj, setArg: Bool::YES] };
      let is_equal = unsafe { msg_send_bool![&obj, isEqual: &*obj] };
      
      // After
      use objc2::msg_send;
      use objc2::rc::{Id, Shared};
      use objc2::runtime::Object;
      
      let obj: Id<Object, Shared>;
      let _: () = unsafe { msg_send![&obj, setArg: true] };
      let is_equal: bool = unsafe { msg_send![&obj, isEqual: &*obj] };
      

    Changed

    • BREAKING: Change syntax in extern_class! macro to be more Rust-like.

    • BREAKING: Change syntax in declare_class! macro to be more Rust-like.

    • BREAKING: Renamed Id::from_owned to Id::into_shared.

    • BREAKING: The return type of msg_send_id! is now more generic; it can now either be Option<Id<_, _>> or Id<_, _> (if the latter, it'll panic if the method returned NULL).

      Example:

      // Before
      let obj: Id<Object, Shared> = unsafe {
          msg_send_id![msg_send_id![class!(MyObject), alloc], init].unwrap()
      };
      
      // After
      let obj: Id<Object, Shared> = unsafe {
          msg_send_id![msg_send_id![class!(MyObject), alloc], init]
      };
      
    • Updated ffi module to objc-sys v0.2.0-beta.2. This includes:

      • Fixed docs.rs setup.
    • BREAKING: Updated encode module objc2-encode v2.0.0-pre.2.

      In particular, Encoding no longer has a lifetime parameter:

      // Before
      #[repr(C)]
      pub struct NSRange {
          pub location: usize,
          pub length: usize,
      }
      unsafe impl Encode for NSRange {
          const ENCODING: Encoding<'static> = Encoding::Struct(
              "_NSRange", // This is how the struct is defined in C header files
              &[usize::ENCODING, usize::ENCODING]
          );
      }
      unsafe impl RefEncode for NSRange {
          const ENCODING_REF: Encoding<'static> = Encoding::Pointer(&Self::ENCODING);
      }
      
      // After
      #[repr(C)]
      pub struct NSRange {
          pub location: usize,
          pub length: usize,
      }
      unsafe impl Encode for NSRange {
          const ENCODING: Encoding = Encoding::Struct(
              "_NSRange", // This is how the struct is defined in C header files
              &[usize::ENCODING, usize::ENCODING]
          );
      }
      unsafe impl RefEncode for NSRange {
          const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
      }
      

    Deprecated

    • Deprecated msg_send_bool! in favour of new functionality on msg_send! that allows seamlessly handling bool.
    Open source →
  18. 0.3.0-beta.1 19 Jul 2022 pre-release
    Release notes

    Added

    • Added msg_send_id! to help with following Objective-C's memory management rules. It is highly recommended that you use this instead of doing memory management yourself!

      Example:

      // Before
      let obj: Id<Object, Shared> = unsafe {
          let obj: *mut Object = msg_send![class!(MyObject), alloc];
          let obj: *mut Object = msg_send![obj, init];
          Id::new(obj).unwrap()
      };
      
      // After
      let obj: Id<Object, Shared> = unsafe {
          msg_send_id![msg_send_id![class!(MyObject), alloc], init].unwrap()
      };
      
    • Added the "unstable-static-sel" and "unstable-static-sel-inlined" feature flags to make the sel! macro (and by extension, the msg_send! macros) faster.

    • Added "unstable-c-unwind" feature.

    • Added unsafe function Id::cast for converting between different types of objects.

    • Added Object::ivar_ptr to allow direct access to instance variables through &Object.

    • Added VerificationError as more specific return type from Class::verify_sel.

    • Added rc::Allocated struct which is used within msg_send_id!.

    • Added Class::responds_to.

    • Added exception::Exception object to improve error messages from caught exceptions.

    • Added declare::Ivar<T> helper struct. This is useful for building safe abstractions that access instance variables.

    • Added Id::from_owned helper function.

    Changed

    • BREAKING: Sel is now required to be non-null, which means that you have to ensure that any selectors you receive from method calls are non-null before using them.

    • BREAKING: ClassBuilder::root is now generic over the function pointer, meaning you will have to coerce initializer functions to pointers like in ClassBuilder::add_method before you can use it.

    • BREAKING: Moved MessageReceiver::verify_message to Class::verify_sel and changed return type.

    • Improved debug output with verify_message feature enabled.

    • BREAKING: Changed MessageReceiver::send_message to panic instead of returning an error.

    • BREAKING: Renamed catch_all feature to catch-all.

    • BREAKING: Made passing the function pointer argument to ClassBuilder::add_method, ClassBuilder::add_class_method and similar more ergonomic.

      Let's say you have the following code:

      // Before
      let init: extern "C" fn(&mut Object, Sel) -> *mut Object = init;
      builder.add_method(sel!(init), init);
      

      Unfortunately, you will now encounter a very confusing error:

        |
      2 | builder.add_method(sel!(init), init);
        |         ^^^^^^^^^^ implementation of `MethodImplementation` is not general enough
        |
         = note: `MethodImplementation` would have to be implemented for the type `for<'r> extern "C" fn(&'r mut Object, Sel) -> *mut Object`
         = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&'0 mut Object, Sel) -> *mut Object`, for some specific lifetime `'0`
      

      To fix this, let the compiler infer the argument and return types:

      // After
      let init: extern "C" fn(_, _) -> _ = init;
      builder.add_method(sel!(init), init);
      
    • Updated ffi module to objc-sys v0.2.0-beta.1. This includes:

      • Added unstable-c-unwind feature.
      • Use doc_auto_cfg to improve documentation output.
    • BREAKING: Updated encode module objc2-encode v2.0.0-pre.1.

    Fixed

    • BREAKING: Disallow throwing nil exceptions in exception::throw.

    Removed

    • BREAKING: Removed the Sel::from_ptr method.
    • BREAKING: Removed MessageError.
    Open source →
  19. 0.3.0-beta.0 13 Jun 2022 pre-release
    Release notes

    Added

    • Added deprecated Object::get_ivar and Object::get_mut_ivar to make upgrading easier.
    • Allow using From/TryFrom to convert between rc::Id and rc::WeakId.
    • Added Bool::as_bool (more descriptive name than Bool::is_true).
    • Added convenience method Id::as_ptr and Id::as_mut_ptr.
    • The objc2-encode dependency is now exposed as objc2::encode.
    • Added Id::retain_autoreleased to allow following Cocoas memory management rules more efficiently.
    • Consistently allow trailing commas in msg_send!.
    • Added msg_send_bool!, a less error-prone version of msg_send! for Objective-C methods that return BOOL.
    • Implemented MethodImplementation for unsafe function pointers.

    Changed

    • BREAKING: Changed signature of Id::new and Id::retain from fn(NonNull<T>) -> Id<T> to fn(*mut T) -> Option<Id<T>>.

      Concretely, you will have to change your code as follows.

      // Before
      let obj: *mut Object = unsafe { msg_send![class!(NSObject), new] };
      let obj = NonNull::new(obj).expect("failed to allocate object");
      let obj = unsafe { Id::new(obj) };
      // After
      let obj: *mut Object = unsafe { msg_send![class!(NSObject), new] };
      let obj = unsafe { Id::new(obj) }.expect("failed to allocate object");
      
    • Allow specifying any receiver T: Message for methods added with ClassBuilder::add_method.

    • Renamed ClassDecl and ProtocolDecl to ClassBuilder and ProtocolBuilder. The old names are kept as deprecated aliases.

    • BREAKING: Changed how msg_send! works wrt. capturing its arguments.

      This will require changes to your code wherever you used Id, for example:

      // Before
      let obj: Id<Object, Owned> = ...;
      let p: i32 = unsafe { msg_send![obj, parameter] };
      let _: () = unsafe { msg_send![obj, setParameter: p + 1] };
      // After
      let mut obj: Id<Object, Owned> = ...;
      let p: i32 = unsafe { msg_send![&obj, parameter] };
      let _: () = unsafe { msg_send![&mut obj, setParameter: p + 1] };
      

      Notice that we now clearly pass obj by reference, and therein also communicate the mutability of the object (in the first case, immutable, and in the second, mutable).

      If you previously used *mut Object or &Object as the receiver, message sending should work exactly as before.

    • BREAKING: Class no longer implements Message (but it can still be used as the receiver in msg_send!, so this is unlikely to break anything in practice).

    • BREAKING: Sealed the MethodImplementation trait, and made its imp method privat.

    • BREAKING: Updated ffi module to objc-sys v0.2.0-beta.0. This includes:

      • BREAKING: Changed links key from objc to objc_0_2 for better future compatibility, until we reach 1.0 (so DEP_OBJC_CC_ARGS in build scripts becomes DEP_OBJC_0_2_CC_ARGS).
      • BREAKING: Apple's runtime is now always the default.
      • BREAKING: Removed type aliases Class, Ivar, Method and Protocol since they could be mistaken for the objc2::runtime structs with the same name.
      • BREAKING: Removed objc_property_t.
      • BREAKING: Removed objc_hook_getClass and objc_hook_lazyClassNamer type aliases (for now).
      • BREAKING: Removed DEP_OBJC_RUNTIME build script output.
    • BREAKING: Updated objc2-encode (Encoding, Encode, RefEncode and EncodeArguments) to v2.0.0-pre.0.

    Fixed

    • Properly sealed the MessageArguments trait (it already had a hidden method, so this is not really a breaking change).

    Removed

    • BREAKING: ManuallyDrop no longer implements Message directly.
    • BREAKING: MessageReceiver::as_raw_receiver is no longer public.
    Open source →
  20. 0.3.0-alpha.6 03 Jan 2022 pre-release
    Release notes

    Added

    • Implement Hash for Sel, Ivar, Class, Method and MessageError.
    • Implement PartialEq and Eq for Ivar, Method and MessageError.
    • Implement fmt::Pointer for Sel and rc::AutoreleasePool.
    • Implement fmt::Debug for ClassDecl, ProtocolDecl and rc::AutoreleasePool.

    Changed

    • BREAKING: Renamed:
      • Object::get_ivar -> Object::ivar
      • Object::get_mut_ivar -> Object::ivar_mut
    • Vastly improved documentation.
    • BREAKING: Updated ffi module to objc-sys v0.2.0-alpha.1. This includes:
      • Added objc_exception_try_enter and objc_exception_try_exit on macOS x86.
      • BREAKING: Correctly cfg-guarded the following types and methods to not be available on macOS x86:
        • objc_exception_matcher
        • objc_exception_preprocessor
        • objc_uncaught_exception_handler
        • objc_exception_handler
        • objc_begin_catch
        • objc_end_catch
        • objc_exception_rethrow
        • objc_setExceptionMatcher
        • objc_setExceptionPreprocessor
        • objc_setUncaughtExceptionHandler
        • objc_addExceptionHandler
        • objc_removeExceptionHandler
      • BREAKING: Removedobjc_set_apple_compatible_objcxx_exceptions since it is only available when libobjc2 is compiled with the correct flags.
      • BREAKING: Removed object_setInstanceVariableWithStrongDefault since it is only available since macOS 10.12.
      • BREAKING: Removed objc_setHook_getClass since it is only available since macOS 10.14.4.
      • BREAKING: Removed objc_setHook_lazyClassNamer since it is only available since macOS 11.
      • Fixed docs.rs configuration.
    • BREAKING: Updated objc2-encode (Encoding, Encode, RefEncode and EncodeArguments) to v2.0.0-beta.2.
    Open source →
  21. 0.3.0-alpha.5 22 Dec 2021 pre-release
    Release notes

    Added

    • Export objc-sys as ffi module.
    • Added common trait impls on rc::Owned and rc::Shared (useful in generic contexts).
    • Implement RefEncode for runtime::Protocol.
    • Added Message and MessageReceiver implementation for ManuallyDrop<T> (where T is appropriately bound). This allows patterns like:
      let obj = Id::new(msg_send![class!(MyObject), alloc]);
      let obj = ManuallyDrop::new(obj);
      // `init` takes ownership and possibly returns a new object.
      let obj = Id::new(msg_send![obj, init]);
      
    • New cargo feature "malloc", which allows cutting down on dependencies, most crates don't need the introspection features that this provides.

    Changed

    • Deprecated runtime::BOOL, runtime::YES and runtime::NO. Use the newtype Bool instead, or low-level ffi::BOOL, ffi::YES and ffi::NO.
    • BREAKING: The following methods now require the new "malloc" feature flag to be enabled:
      • MessageReceiver::verify_message (temporarily)
      • Method::return_type
      • Method::argument_type
      • Class::classes
      • Class::instance_methods
      • Class::adopted_protocols
      • Class::instance_variables
      • Protocol::protocols
      • Protocol::adopted_protocols
    • Relaxed Sized bound on rc::Id and rc::WeakId to prepare for extern type support.
    • BREAKING: Relaxed Sized bound on rc::SliceId and rc::DefaultId.
    • BREAKING: Updated objc-sys to v0.2.0-alpha.0. This includes:
      • Added NSInteger and NSUInteger (type aliases of isize/usize).
      • Added NSIntegerMax, NSIntegerMin and NSUIntegerMax.
      • BREAKING: Changed cfg-guarded class_getImageName to only appear on Apple platforms.
      • BREAKING: Opaque types are now also !UnwindSafe.
    • Updated objc2-encode (Encoding, Encode, RefEncode and EncodeArguments) to v2.0.0-beta.1.

    Removed

    • BREAKING: Removed the raw FFI functions from the runtime module. These are available in the new ffi module instead.

    Fixed

    • An issue with inlining various rc methods.
    • Most types (e.g. Class and Method) are now Send, Sync, UnwindSafe and RefUnwindSafe again. Notable exception is Object, because that depends on the specific subclass.
    Open source →
  22. 0.3.0-alpha.4 22 Nov 2021 pre-release
    Release notes

    Note: To use this version, specify objc2-encode = "=2.0.0-beta.0" in your Cargo.toml as well.

    Added

    • BREAKING: GNUStep users must depend on, and specify the appropriate feature flag on objc-sys for the version they're using.
    • Moved objc_exception crate into exception module (under feature flag).
    • Added support for _Complex types.
    • Added rc::SliceId, rc::SliceIdMut and rc::DefaultId helper traits for extra functionality on rc::Id.

    Changed

    • BREAKING: The exception feature now only enables the exception module, for general use. Use the new catch_all feature to wrap all message sends in a @try/@catch.
    • BREAKING: Updated objc-sys to v0.1.0. This includes:
      • BREAKING: Use feature flags apple, gnustep-X-Y or winobjc to specify the runtime you're using, instead of the RUNTIME_VERSION environment variable.
      • BREAKING: DEP_OBJC_RUNTIME now returns gnustep on WinObjC.
    • BREAKING: Updated objc2-encode (Encoding, Encode, RefEncode and EncodeArguments) to v2.0.0-beta.0.
    Open source →
  23. 0.3.0-alpha.3 22 Nov 2021 pre-release
    Release notes

    Note: To use this version, specify objc2-encode = "=2.0.0-alpha.1" in your Cargo.toml as well.

    Added

    • Now uses the objc-sys (v0.0.1) crate for possibly better interoperability with other crates that link to libobjc.
    • Added newtype runtime::Bool to fix soundness issues with using runtime::BOOL or bool.
    • Moved objc_id crate into rc module. Notable changes:
      • Vastly improved documentation
      • Added Id::autorelease
      • Added Id::from_shared
      • Added a lot of forwarding implementations on Id for easier use
      • Id and WeakId are now able to use the null-pointer optimization
      • BREAKING: Added T: Message bounds on Id
      • BREAKING: Remove ShareId type alias
      • BREAKING: Id no longer have a default Ownership, you must specify it everywhere as either Id<T, Shared> or Id<T, Owned>
      • BREAKING: Sealed the Ownership trait
      • BREAKING: Renamed Id::from_ptr to Id::retain
      • BREAKING: Renamed Id::from_retained_ptr to Id::new
      • BREAKING: Changed Id::share to a From implementation (usage of obj.share() can be changed to obj.into())
      • BREAKING: Fixed soundness issues with missing Send and Sync bounds on Id and WeakId
    • Added sealed (for now) trait MessageReceiver to specify types that can be used as the receiver of a message (instead of only allowing pointer types).
    • Add MessageReceiver::send_super_message method for dynamic selectors.

    Changed

    • BREAKING: Change types of parameters to FFI functions exported in the runtime module.
    • BREAKING: Most types are now !UnwindSafe, to discourage trying to use them after an unwind. This restriction may be lifted in the future.
    • BREAKING: Most types are now !Send and !Sync. This was an oversight that is fixed in a later version.
    • A lot of smaller things.
    • BREAKING: Dynamic message sending with Message::send_message is moved to MessageReceiver.
    • BREAKING Make MessageArguments a subtrait of EncodeArguments.
    • Allow an optional comma after each argument to msg_send!.

    Removed

    • BREAKING: Removed rc::StrongPtr. Use Option<rc::Id<Object, Shared>> instead (beware: This has stronger safety invariants!).
    • BREAKING: Removed rc::WeakPtr. Use rc::WeakId<Object> instead.

    Fixed

    • BREAKING: Stop unsafely dereferencing msg_send!s first argument. The MessageReceiver trait was introduced to avoid most breakage from this change.
    Open source →
  24. 0.3.0-alpha.2 22 Nov 2021 pre-release
    Release notes

    Added

    • Added rc::AutoreleasePool and rc::AutoreleaseSafe to make accessing autoreleased objects safe, by binding references to it using the ptr_as_ref and ptr_as_mut methods.

    Changed

    • BREAKING: The closure in rc::autoreleasepool now takes an argument &rc::AutoreleasePool. This reference can be given to functions like INSString::as_str so that it knows which lifetime to bound the returned &str with.

      // Before
      autoreleasepool(|| {
          // Some code that autoreleases objects
      });
      
      // After
      autoreleasepool(|_pool| {
          // Some code that autoreleases objects
      });
      

    Fixed

    • The encoding of BOOL on GNUStep.
    Open source →
  25. 0.3.0-alpha.1 22 Nov 2021 pre-release
    Release notes

    Added

    • More documentation of safety requirements, and in general.

    Changed

    • BREAKING: Change objc-encode dependency to objc2-encode version 2.0.0-alpha.1, and re-export the new RefEncode trait from that.

    • BREAKING: Require that the receiver, arguments and return types of messages always implement Encode. This helps ensuring that only types made to go across the FFI boundary (repr(C), ...) may. These requirements were already present when the verify_message feature was enabled.

      This is a very disruptive change, since libraries are now required to implement Encode and RefEncode for all types intended to go across the FFI-boundary to Objective-C. The change is justified because it helps ensuring that users only pass valid types to msg_send! (for example, this prevents users from accidentally passing Drop types to msg_send).

      See the following examples for how to implement these traits, and otherwise refer to the documentation of objc2-encode (v2.0.0-alpha.1 or above).

      use objc2::{Encode, Encoding, RefEncode};
      
      /// Example struct.
      #[repr(C)]
      pub struct NSRange {
          pub location: usize,
          pub length: usize,
      }
      unsafe impl Encode for NSRange {
          const ENCODING: Encoding<'static> = Encoding::Struct(
              "_NSRange", // This is how the struct is defined in C header files
              &[usize::ENCODING, usize::ENCODING]
          );
      }
      unsafe impl RefEncode for NSRange {
          const ENCODING_REF: Encoding<'static> = Encoding::Pointer(&Self::ENCODING);
      }
      
      /// Example object.
      #[repr(C)]
      pub struct __CFString(c_void);
      
      pub type CFStringRef = *const __CFString;
      
      unsafe impl RefEncode for __CFString {
          const ENCODING_REF: Encoding<'static> = Encoding::Object;
      }
      
    • Temporarily disabled iOS tests.

    Fixed

    • Statically find the correct objc_msgSend[_X] function to use based on the Encode implementation of the return type. This fixes using functions that return e.g. type CGFloat = f32 / f64;.
    • Documentation links.
    Open source →
  26. 0.3.0-alpha.0 19 Nov 2021 pre-release
    Release notes

    Note: This is the version that is, as of this writing, available on the master branch in the original objc project.

    Added

    • Improve macro hygiene.
      // You can now do
      use objc2::{sel, class, msg_send};
      // Instead of
      #[macro_use]
      extern crate objc2;
      
    • Update to Rust 2018.
    • Other internal improvements.

    Changed

    • BREAKING: Forked the project, so the crate name is now objc2.

    • BREAKING: Updated encoding utilities to use objc-encode. See that for how to use the updated type Encoding and trait Encode.

      In short, you will likely need to change your implementations of Encode like this:

      use objc2::{Encode, Encoding};
      
      pub type CGFloat = ...; // Varies based on target_pointer_width
      
      #[repr(C)]
      pub struct NSPoint {
          pub x: CGFloat,
          pub y: CGFloat,
      }
      
      // Before
      unsafe impl Encode for NSPoint {
          fn encode() -> Encoding {
              let encoding = format!(
                  "{{CGPoint={}{}}}",
                  CGFloat::encode().as_str(),
                  CGFloat::encode().as_str(),
              );
              unsafe { Encoding::from_str(&encoding) }
          }
      }
      
      // After
      unsafe impl Encode for NSPoint {
          const ENCODING: Encoding<'static> = Encoding::Struct(
              "CGPoint",
              &[CGFloat::ENCODING, CGFloat::ENCODING]
          );
      }
      
    • BREAKING: Updated public dependency malloc_buf to 1.0.

    • BREAKING: Method::return_type and Method::argument_type now return Malloc<str> instead of Encoding.

    • BREAKING: Ivar::type_encoding now return &str instead of Encoding.

    Removed

    • BREAKING: Removed hidden sel_impl! macro.
    Open source →
  27. 0.2.7 19 Nov 2021
    Release notes

    Fixed

    • BREAKING: Uses of msg_send! will now correctly fail to compile if no return type can be inferred, instead of relying on an edge case of the compiler that will soon change and silently cause undefined behavior.
    Open source →

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive