48 KiB
Changelog
Notable changes to this crate will be documented in this file.
The format is based on Keep a Changelog.
Unreleased - YYYY-MM-DD
0.5.2 - 2024-05-21
Added
- Added
Retained::autorelease_ptr. - Added the feature flag
"relax-sign-encoding", which when enabled, allows using e.g.NSIntegerin places where you would otherwise have to useNSUInteger.
Changed
-
Renamed
IdtoRetained, 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::WeakIdtorc::Weak.rc::DefaultIdtorc::DefaultRetained.rc::IdFromIteratortorc::RetainedFromIterator.rc::IdIntoIteratortorc::RetainedIntoIterator.
Deprecated
- Deprecated the
appleCargo feature flag, it is assumed by default on Apple platforms.
0.5.1 - 2024-04-17
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_rawas the oppositve ofId::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
ClassBuilderandProtocolBuilderfrom thedeclaremodule to theruntimemodule. The old locations are deprecated. - Enabled the
"verify"feature flag's functionality when debug assertions are enabled. - Renamed
Id::newtoId::from_raw. The previous name is kept as a deprecated alias.
0.5.0 - 2023-12-03
Added
- Added the following traits to the
mutabilitymodule (see the documentation for motivation and usage info):HasStableHash.IsAllowedMutable.IsMainThreadOnly.CounterpartOrSelf.
- Added new
encodetraitsEncodeReturn,EncodeArgumentandEncodeArguments. - Added methods
as_ptrandas_mut_ptrtoAllocated. - Added optimization for converting
msg_send_id![cls, alloc]to a call to the faster runtime functionobjc_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 newrc::PartialInit. - Added the ability for
msg_send_id!to callsupermethods. - Implement
SendandSyncforProtocolObjectif the underlying protocol implements it. - Added ability to create
SendandSyncversions ofProtocolObject<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
DeclaredClasstrait 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_selnow take more well-defined typesEncodeArgumentsandEncodeReturn. -
BREAKING: Changed how the
mutabilitytraits work; these no longer haveClassTypeas a super trait, allowing them to work forProtocolObjectas well.This effectively means you can now
copyaProtocolObject<dyn NSCopying>. -
BREAKING: Allow implementing
DefaultIdfor any type, not just those who areIsAllocableAnyThread. -
BREAKING: Moved the
MethodImplementationtrait from thedeclaremodule to theruntimemodule. -
BREAKING: Moved the
MessageReceivertrait to theruntimemodule. -
BREAKING: Make the
MessageReceivertrait no longer implemented for references toId. Dereference theIdyourself.Note: Passing
&Idinmsg_send!is still supported. -
BREAKING:
MessageReceiver::send_messageandMessageReceiver::send_super_messagenow takeEncodeArgumentsand returnEncodeReturn, instead of internal traits.This is done to make
MessageReceivermore straightforward to understand, although it now also has slightly less functionality thanmsg_send!.In particular automatic conversion of
boolis not supported inMessageReceiver. -
Relaxed the requirements for receivers in
MethodImplementation; now, anything that implementsMessageReceivercan be used as the receiver of a method. -
BREAKING: Renamed the associated types
RetandArgsonMethodImplementationtoReturnandArguments. -
BREAKING: Make
rc::Allocatedallowed to beNULLinternally, such that uses ofOption<Allocated<T>>is now simplyAllocated<T>. -
AnyObject::classnow returns a'staticreference to the class. -
Relaxed
ProtocolTyperequirement onProtocolObject. -
BREAKING: Updated
encodetypes to those fromobjc2-encode v4.0.0.
Deprecated
-
Soft deprecated using
msg_send!without a comma between arguments (i.e. deprecated when the"unstable-msg-send-always-comma"feature is enabled).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, owner: obj, userData: ptr::null_mut::<c_void>(), assumeInside: false, ];
Fixed
-
Fixed the name of the protocol that
NSObjectProtocolreferences. -
Allow cloning
Id<AnyObject>. -
BREAKING: Restrict message sending to
&mutreferences to things that implementIsAllowedMutable. -
Disallow the ability to use non-
Self-like types as the receiver indeclare_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_ptrandload_mutmethods onIvar, instead of theivar,ivar_ptrandivar_mutmethods onAnyObject.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
RefEncodenormally forc_void. This makesAtomicPtr<c_void>implementEncode.
Removed
-
BREAKING: Removed
ProtocolTypeimplementation forNSObject. Use the more preciseNSObjectProtocoltrait instead! -
BREAKING: Removed the
MessageArgumentstrait. -
BREAKING: Removed the following items from the
declaremodule:Ivar,IvarEncode,IvarBool,IvarDrop,IvarTypeandInnerIvarType.Ivar functionality is available in a different form now, see above under "Changed".
-
BREAKING: Removed
ClassBuilder::add_static_ivar.
0.4.1 - 2023-07-31
Added
- Allow using
MainThreadMarkerinextern_methods!. - Added the feature flag
"relax-void-encoding", which when enabled, allows using*mut c_voidin a few places where you would otherwise have to specify the encoding precisely.
Changed
-
Renamed
runtimetypes:ObjecttoAnyObject.ClasstoAnyClass.ProtocoltoAnyProtocol.
To better fit with Swift's naming scheme. The types are still available under the old names as deprecated aliases.
Fixed
-
BREAKING: Updated
encodetypes to those fromobjc2-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.
0.4.0 - 2023-06-20
Added
-
Added
objc2::rc::autoreleasepool_leaking, and improve performance of objectsDebugimpls. -
BREAKING: Added associated type
ClassType::Mutability, which replaces the ownership type onId, 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&Tto anId<T>. -
Added
mutabilitymodule, containing various types that can be specified for the above. -
Preliminary support for specifying
wherebounds on methods insideextern_protocol!andextern_methods!. -
Allow arbitary expressions in
const NAMEinextern_class!,extern_protocol!anddeclare_class!. -
Added
rc::IdIntoIteratorhelper trait and forwardingIntoIteratorimplementations forrc::Id. -
Added
rc::IdFromIteratorhelper trait for implementingIntoIteratorforrc::Id. -
Added
Displayimpl forruntime::Class,runtime::Selandruntime::Protocol. -
Added
Debugimpl forruntime::Methodandruntime::Ivar. -
Added
Method::set_implementation. -
Added
Method::exchange_implementation. -
Added
Object::set_class.
Changed
-
BREAKING:
objc2::rc::AutoreleasePoolis now a zero-sizedCopytype with a lifetime parameter, instead of the lifetime parameter being the reference it was behind. -
BREAKING: Made
Id::autoreleaseandId::autorelease_returnbe associated functions instead of methods. This means they now have to be called asId::autorelease(obj, pool)instead ofobj.autorelease(pool).Additionally, rename the mutable version to
Id::autorelease_mut. -
BREAKING: Moved
VerificationError,ProtocolObjectandImplementedByinto theruntimemodule. -
Relaxed a
fmt::Debugbound onWeakId's ownfmt::Debugimpl. -
Changed
Debugimpl forruntime::Class,runtime::Selandruntime::Protocolto give more information. -
BREAKING: Updated
encodemodule toobjc2-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 outsideobjc2from the layout guarantees ofrc::Id. -
BREAKING: Removed
Ownershiptype parameter fromId, as well asrc::Ownership,rc::Owned,rc::Shared,Id::from_sharedandId::into_shared. This functionality has been moved from being at the "usage-level", to being moved to the "type-level" in the associated typeClassType::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
&mutto 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 thanWeakId::load. -
BREAKING: Removed forwarding
Iteratorimplementation forId, since it conflicts with theIntoIteratorimplementation that it now has instead.
0.3.0-beta.5 - 2023-02-07
Added
-
Support
#[cfg(...)]attributes inextern_class!macro. -
Added support for selectors with multiple colons like
abc::in thesel!,extern_class!,extern_protocol!anddeclare_class!macros. -
Added ability to use
#[method_id(mySelector:)]insidedeclare_class!, like you would do inextern_methods!. -
Added 16-fold impls for
EncodeArguments,MessageArguments, andMethodImplementation. -
Added
NSObjectProtocoltrait for allowingProtocolObjectto implementDebug,Hash,PartialEqandEq. -
Support running
Dropimpls ondeallocindeclare_class!. -
Added
declare::IvarEncodeanddeclare::IvarBooltypes. -
BREAKING: Moved the
objc2_encodetraits toobjc2::encode.This includes removing the
EncodeConvertandEncodeArgumentstraits. -
Added support for out-parameters like
&mut Id<_, _>inmsg_send!,msg_send_id!andextern_methods!.
Changed
-
BREAKING: Using the automatic
NSError**-to-Resultfunctionality inextern_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
ConformsTotrait has similarly been removed, and theImplementedBytrait andProtocolObjectstruct has been introduced instead. -
BREAKING: Moved
NSObject::is_kind_ofto the newNSObjectProtocol. -
BREAKING: Removed support for custom
deallocimpls indeclare_class!. ImplementDropfor 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
ffimodule toobjc-sys v0.3.0. -
BREAKING: Updated
encodemodule toobjc2-encode v2.0.0-pre.4.
Fixed
- Allow empty structs in
declare_class!macro. - Allow using
extern_methods!without theClassTypetrait in scope. - Fixed a few small issues with
declare_class!. - Fixed
()being possible in argument position inmsg_send!.
0.3.0-beta.4 - 2022-12-24
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 ofmsg_send!/msg_send_id!, and have it automatically return aResult<..., 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 theNSError**parameter. -
Added
#[method_id(...)]attribute toextern_methods!. -
Added
"verify"feature as a replacement for the"verify_message"feature. -
Added
extern_protocol!macro andProtocolTypetrait. -
Added
ConformsTotrait for marking that a type conforms to a specific protocol. -
Added
Encodeimpl forOption<Sel>. -
Added
objc2::runtime::NSObject- before, this was only available underobjc2::foundation::NSObject. -
Added
objc2::runtime::NSZone- before, this was only available underobjc2::foundation::NSZone.
Changed
- Allow other types than
&Classas the receiver inmsg_send_id!methods of thenewfamily. - BREAKING: Changed the
Allocatedstruct to be used asAllocated<T>instead ofId<Allocated<T>, O>. - Verify the message signature of overriden methods when declaring classes if
the
verifyfeature is enabled. - Verify in
declare_class!that protocols are implemented correctly. - BREAKING: Changed the name of the attribute macro in
extern_methodsfrom#[sel(...)]to#[method(...)]. - BREAKING: Changed
extern_methods!anddeclare_class!such that associated functions whoose first parameter is calledthis, is treated as instance methods instead of class methods. - BREAKING: Message verification is now enabled by default. Your message
sends might panic with
debug_assertionsenabled if they are detected to be invalid. Test your code to see if that is the case! - BREAKING:
declare_class!usesConformsTo<...>instead of the temporaryProtocol<...>syntax. - Require implementors of
Messageto support weak references. - BREAKING: Moved
objc2::foundationintoicrate::Foundation. - BREAKING: Moved
objc2::ns_stringintoicrate::ns_string. - Updated
ffimodule toobjc-sys v0.2.0-beta.3. - BREAKING: Updated
encodemoduleobjc2-encode v2.0.0-pre.3.
Fixed
- Fixed duplicate selector extraction in
extern_methods!. - Fixed using
deprecatedattributes indeclare_class!. - Fixed
cfgattributes on methods and implementations indeclare_class!.
Removed
- BREAKING: Removed
"verify_message"feature. It has been mostly replaced bydebug_assertionsand the"verify"feature.
0.3.0-beta.3 - 2022-09-01
Added
- Added
Ivar::write,Ivar::as_ptrandIvar::as_mut_ptrfor safely querying and modifying instance variables insideinitmethods. - Added
IvarDrop<T>to allow storing complexDropvalues in ivars (currentlyrc::Id<T, O>,Box<T>,Option<rc::Id<T, O>>orOption<Box<T>>). - BREAKING: Added required
ClassType::NAMEconstant for statically determining the name of a specific class. - Allow directly specifying class name in
declare_class!macro.
Removed
- BREAKING:
MaybeUninitno longer implementsIvarTypedirectly; useIvar::writeinstead.
0.3.0-beta.2 - 2022-08-28
Added
-
Added the
"unstable-static-class"and"unstable-static-class-inlined"feature flags to make theclass!macro zero cost. -
Moved the external crate
objc2_foundationintoobjc2::foundationunder (default) feature flag"foundation". -
Added
declare_class!,extern_class!andns_string!macros fromobjc2-foundation. -
Added helper method
ClassBuilder::add_static_ivar. -
BREAKING: Added
ClassTypetrait, and moved the associatedclassmethods thatextern_class!anddeclare_class!generated to that. This means you'll have touse objc2::ClassTypewhenever 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
boolto/from the Objective-CBOOLinmsg_send!,msg_send_id!,extern_methods!anddeclare_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_ownedtoId::into_shared. -
BREAKING: The return type of
msg_send_id!is now more generic; it can now either beOption<Id<_, _>>orId<_, _>(if the latter, it'll panic if the method returnedNULL).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
ffimodule toobjc-sys v0.2.0-beta.2. -
BREAKING: Updated
encodemoduleobjc2-encode v2.0.0-pre.2.In particular,
Encodingno 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
- Depreacted
msg_send_bool!in favour of new functionality onmsg_send!that allows seamlessly handlingbool.
0.3.0-beta.1 - 2022-07-19
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 thesel!macro (and by extension, themsg_send!macros) faster. -
Added
"unstable-c-unwind"feature. -
Added unsafe function
Id::castfor converting between different types of objects. -
Added
Object::ivar_ptrto allow direct access to instance variables through&Object. -
Added
VerificationErroras more specific return type fromClass::verify_sel. -
Added
rc::Allocatedstruct which is used withinmsg_send_id!. -
Added
Class::responds_to. -
Added
exception::Exceptionobject 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_ownedhelper function.
Changed
-
BREAKING:
Selis 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::rootis now generic over the function pointer, meaning you will have to coerce initializer functions to pointers like inClassBuilder::add_methodbefore you can use it. -
BREAKING: Moved
MessageReceiver::verify_messagetoClass::verify_seland changed return type. -
Improved debug output with
verify_messagefeature enabled. -
BREAKING: Changed
MessageReceiver::send_messageto panic instead of returning an error. -
BREAKING: Renamed
catch_allfeature tocatch-all. -
BREAKING: Made passing the function pointer argument to
ClassBuilder::add_method,ClassBuilder::add_class_methodand 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
ffimodule toobjc-sys v0.2.0-beta.1. -
BREAKING: Updated
encodemoduleobjc2-encode v2.0.0-pre.1.
Fixed
- BREAKING: Disallow throwing
nilexceptions inexception::throw.
Removed
- BREAKING: Removed the
Sel::from_ptrmethod. - BREAKING: Removed
MessageError.
0.3.0-beta.0 - 2022-06-13
Added
- Added deprecated
Object::get_ivarandObject::get_mut_ivarto make upgrading easier. - Allow using
From/TryFromto convert betweenrc::Idandrc::WeakId. - Added
Bool::as_bool(more descriptive name thanBool::is_true). - Added convenience method
Id::as_ptrandId::as_mut_ptr. - The
objc2-encodedependency is now exposed asobjc2::encode. - Added
Id::retain_autoreleasedto allow following Cocoas memory management rules more efficiently. - Consistently allow trailing commas in
msg_send!. - Added
msg_send_bool!, a less error-prone version ofmsg_send!for Objective-C methods that returnBOOL. - Implemented
MethodImplementationforunsafefunction pointers.
Changed
-
BREAKING: Changed signature of
Id::newandId::retainfromfn(NonNull<T>) -> Id<T>tofn(*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: Messagefor methods added withClassBuilder::add_method. -
Renamed
ClassDeclandProtocolDecltoClassBuilderandProtocolBuilder. 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
objby 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 Objector&Objectas the receiver, message sending should work exactly as before. -
BREAKING:
Classno longer implementsMessage(but it can still be used as the receiver inmsg_send!, so this is unlikely to break anything in practice). -
BREAKING: Sealed the
MethodImplementationtrait, and made itsimpmethod privat. -
BREAKING: Updated
ffimodule toobjc-sys v0.2.0-beta.0. -
BREAKING: Updated
objc2-encode(Encoding,Encode,RefEncodeandEncodeArguments) tov2.0.0-pre.0.
Fixed
- Properly sealed the
MessageArgumentstrait (it already had a hidden method, so this is not really a breaking change).
Removed
- BREAKING:
ManuallyDropno longer implementsMessagedirectly. - BREAKING:
MessageReceiver::as_raw_receiveris no longer public.
0.3.0-alpha.6 - 2022-01-03
Added
- Implement
HashforSel,Ivar,Class,MethodandMessageError. - Implement
PartialEqandEqforIvar,MethodandMessageError. - Implement
fmt::PointerforSelandrc::AutoreleasePool. - Implement
fmt::DebugforClassDecl,ProtocolDeclandrc::AutoreleasePool.
Changed
- BREAKING: Renamed:
Object::get_ivar->Object::ivarObject::get_mut_ivar->Object::ivar_mut
- Vastly improved documentation.
- BREAKING: Updated
ffimodule toobjc-sys v0.2.0-alpha.1. - BREAKING: Updated
objc2-encode(Encoding,Encode,RefEncodeandEncodeArguments) tov2.0.0-beta.2.
0.3.0-alpha.5 - 2021-12-22
Added
- Export
objc-sysasffimodule. - Added common trait impls on
rc::Ownedandrc::Shared(useful in generic contexts). - Implement
RefEncodeforruntime::Protocol. - Added
MessageandMessageReceiverimplementation forManuallyDrop<T>(whereTis 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::YESandruntime::NO. Use the newtypeBoolinstead, or low-levelffi::BOOL,ffi::YESandffi::NO. - BREAKING: The following methods now require the new
"malloc"feature flag to be enabled:MessageReceiver::verify_message(temporarily)Method::return_typeMethod::argument_typeClass::classesClass::instance_methodsClass::adopted_protocolsClass::instance_variablesProtocol::protocolsProtocol::adopted_protocols
- Relaxed
Sizedbound onrc::Idandrc::WeakIdto prepare forextern typesupport. - BREAKING: Relaxed
Sizedbound onrc::SliceIdandrc::DefaultId. - BREAKING: Updated
objc-systov0.2.0-alpha.0. - Updated
objc2-encode(Encoding,Encode,RefEncodeandEncodeArguments) tov2.0.0-beta.1.
Removed
- BREAKING: Removed the raw FFI functions from the
runtimemodule. These are available in the newffimodule instead.
Fixed
- An issue with inlining various
rcmethods. - Most types (e.g.
ClassandMethod) are nowSend,Sync,UnwindSafeandRefUnwindSafeagain. Notable exception isObject, because that depends on the specific subclass.
0.3.0-alpha.4 - 2021-11-22
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-sysfor the version they're using. - Moved
objc_exceptioncrate intoexceptionmodule (under feature flag). - Added support for
_Complextypes. - Added
rc::SliceId,rc::SliceIdMutandrc::DefaultIdhelper traits for extra functionality onrc::Id.
Changed
- BREAKING: The
exceptionfeature now only enables theexceptionmodule, for general use. Use the newcatch_allfeature to wrap all message sends in a@try/@catch. - BREAKING: Updated
objc-systov0.1.0. - BREAKING: Updated
objc2-encode(Encoding,Encode,RefEncodeandEncodeArguments) tov2.0.0-beta.0.
0.3.0-alpha.3 - 2021-09-05
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 tolibobjc. - Added newtype
runtime::Boolto fix soundness issues with usingruntime::BOOLorbool. - Moved
objc_idcrate intorcmodule. Notable changes:- Vastly improved documentation
- Added
Id::autorelease - Added
Id::from_shared - Added a lot of forwarding implementations on
Idfor easier use IdandWeakIdare now able to use the null-pointer optimization- BREAKING: Added
T: Messagebounds onId - BREAKING: Remove
ShareIdtype alias - BREAKING:
Idno longer have a defaultOwnership, you must specify it everywhere as eitherId<T, Shared>orId<T, Owned> - BREAKING: Sealed the
Ownershiptrait - BREAKING: Renamed
Id::from_ptrtoId::retain - BREAKING: Renamed
Id::from_retained_ptrtoId::new - BREAKING: Changed
Id::shareto aFromimplementation (usage ofobj.share()can be changed toobj.into()) - BREAKING: Fixed soundness issues with missing
SendandSyncbounds onIdandWeakId
- Added sealed (for now) trait
MessageReceiverto specify types that can be used as the receiver of a message (instead of only allowing pointer types). - Add
MessageReceiver::send_super_messagemethod for dynamic selectors.
Changed
- BREAKING: Change types of parameters to FFI functions exported in the
runtimemodule. - 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
!Sendand!Sync. This was an oversight that is fixed in a later version. - A lot of smaller things.
- BREAKING: Dynamic message sending with
Message::send_messageis moved toMessageReceiver. - BREAKING Make
MessageArgumentsa subtrait ofEncodeArguments. - Allow an optional comma after each argument to
msg_send!.
Removed
- BREAKING: Removed
rc::StrongPtr. UseOption<rc::Id<Object, Shared>>instead (beware: This has stronger safety invariants!). - BREAKING: Removed
rc::WeakPtr. Userc::WeakId<Object>instead.
Fixed
- BREAKING: Stop unsafely dereferencing
msg_send!s first argument. TheMessageReceivertrait was introduced to avoid most breakage from this change.
0.3.0-alpha.2 - 2021-09-05
Added
- Added
rc::AutoreleasePoolandrc::AutoreleaseSafeto make accessing autoreleased objects safe, by binding references to it using theptr_as_refandptr_as_mutmethods.
Changed
-
BREAKING: The closure in
rc::autoreleasepoolnow takes an argument&rc::AutoreleasePool. This reference can be given to functions likeINSString::as_strso that it knows which lifetime to bound the returned&strwith.// Before autoreleasepool(|| { // Some code that autoreleases objects }); // After autoreleasepool(|_pool| { // Some code that autoreleases objects });
Fixed
- The encoding of
BOOLonGNUStep.
0.3.0-alpha.1 - 2021-09-02
Added
- More documentation of safety requirements, and in general.
Changed
-
BREAKING: Change
objc-encodedependency toobjc2-encodeversion2.0.0-alpha.1, and re-export the newRefEncodetrait 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 theverify_messagefeature was enabled.This is a very disruptive change, since libraries are now required to implement
EncodeandRefEncodefor 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 tomsg_send!(for example, this prevents users from accidentally passingDroptypes tomsg_send).See the following examples for how to implement these traits, and otherwise refer to the documentation of
objc2-encode(v2.0.0-alpha.1or 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 theEncodeimplementation of the return type. This fixes using functions that return e.g.type CGFloat = f32 / f64;. - Documentation links.
0.3.0-alpha.0 - 2021-08-29
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 typeEncodingand traitEncode.In short, you will likely need to change your implementations of
Encodelike 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_bufto1.0. -
BREAKING:
Method::return_typeandMethod::argument_typenow returnMalloc<str>instead ofEncoding. -
BREAKING:
Ivar::type_encodingnow return&strinstead ofEncoding.
Removed
- BREAKING: Removed hidden
sel_impl!macro.
0.2.7 (objc crate) - 2019-10-19
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.
0.2.6 (objc crate) - 2019-03-25
Fixed
- Suppressed a deprecation warning in
sel!,msg_send!, andclass!.
0.2.5 (objc crate) - 2018-07-24
Added
- BREAKING:
autoreleasepoolreturns the value returned by its body closure.
0.2.4 (objc crate) - 2018-07-22
Added
- Added an
rcmodule with reference counting utilities:StrongPtr,WeakPtr, andautoreleasepool. - Added some reference counting ABI foreign functions to the
runtimemodule.
Fixed
- Messaging nil under GNUstep now correctly returns zeroed results for all return types.
0.2.3 (objc crate) - 2018-07-07
Added
- Added a
class!macro for getting statically-known classes. The result is non-optional (avoiding a need to unwrap) and cached so each usage will only look up the class once. - Added caching to the
sel!macro so that each usage will only register the selector once.
Fixed
- Implementation of
objc2::runtimestructs so there can't be unsound references to uninhabited types.
0.2.2 (objc crate) - 2016-10-30
Added
- Implemented
SyncandSendforSel.
0.2.1 (objc crate) - 2016-04-23
Added
- Added support for working with protocols with the
Protocolstruct. The protocols a class conforms to can be examined with the newClass::adopted_protocolsandClass::conforms_tomethods. - Protocols can be declared using the new
ProtocolDeclstruct.
0.2.0 (objc crate) - 2016-03-20
Added
- Added verification for the types used when sending messages.
This can be enabled for all messages with the
"verify_message"feature, or you can test before sending specific messages with theMessage::verify_messagemethod. Verification errors are reported using the newMessageErrorstruct. - Added support for the GNUstep runtime! Operating systems besides OSX and iOS will fall back to the GNUstep runtime.
- Root classes can be declared by using the
ClassDecl::rootconstructor.
Changed
- BREAKING: C types are now used from
std::os::rawrather thanlibc. This meansEncodemay not be implemented forlibctypes; switch them to thestd::os::rawequivalents instead. This avoids an issue that would arise from simultaneously using different versions of the libc crate. - BREAKING: Dynamic messaging was moved into the
Messagetrait; instead of().send(obj, sel!(description)), useobj.send_message(sel!(description), ()). - BREAKING: Rearranged the parameters to
ClassDecl::newfor consistency; instead ofClassDecl::new(superclass, "MyObject"), useClassDecl::new("MyObject", superclass). - BREAKING: Overhauled the
MethodImplementationtrait. Encodings are now accessed through theMethodImplementation::Argsassociated type. Theimp_formethod was replaced withimpand no longer takes a selector or returns anUnequalArgsError, althoughClassDecl::add_methodstill validates the number of arguments. - BREAKING: Updated the definition of
Impto not use the old dispatch prototypes. To invoke anImp, it must first be transmuted to the correct type.
Removed
BREAKING: objc_msgSend functions from the runtime module; the
availability of these functions varies and they shouldn't be called without
trasmuting, so they are now hidden as an implementation detail of messaging.
Fixed
- Corrected alignment of ivars in
ClassDecl; declared classes may now have a smaller size. - With the
"exception"or"verify_message"feature enabled, panics frommsg_send!will now be triggered from the line and file where the macro is used, rather than from within the implementation of messaging.
0.1.8 (objc crate) - 2015-11-06
Changed
- Updated
libcdependency.
0.1.7 (objc crate) - 2015-09-23
Fixed
improper_ctypeswarning.
0.1.6 (objc crate) - 2015-08-08
Added
- Added
"exception"feature which catches Objective-C exceptions and turns them into Rust panics. - Added support for
ARM,ARM64andx86architectures. - BREAKING: Added
Anybound on message return types. In practice this probably won't break anything. - Start testing on iOS.
0.1.5 (objc crate) - 2015-05-02
Changed
- BREAKING: Renamed
IntoMethodImptoMethodImplementation. - BREAKING: Renamed
MethodImplementation::into_impto::imp_for. - BREAKING: Relaxed
Sizedbounds onEncodeandMessage. In practice this probably won't break anything.
Removed
- BREAKING: Removed
Id,Owned,Ownership,Shared,ShareIdandWeakId. Use them from theobjc_idcrate instead. - BREAKING: Removed
Method::set_implementationandMethod::exchange_implementation.
0.1.4 (objc crate) - 2015-04-17
Removed
- BREAKING: Removed
blockmodule. Use them from theblockcrate instead.
0.1.3 (objc crate) - 2015-04-11
Added
- Implement
fmt::PointerforId.
Fixed
- Odd lifetime bug.
0.1.2 (objc crate) - 2015-04-04
Fixed
- BREAKING: Replace uses of
PhantomFnwithSized.
0.1.1 (objc crate) - 2015-03-27
Added
- Implement
ErrorforUnequalArgsError.
Removed
- BREAKING: Move
objc::foundationinto new crateobjc_foundation.