Skip to content

Commit 78d1cf6

Browse files
committed
Move ivars back into define_class!
This has a better `Debug` impl, is shorter, and is more in line with what the user would expect. It also allows us to extend it in the future with an attribute like `#[name = "my_ivar"]` on the field to make the ivar publicly visible on the class (which is important for KVO), and maybe even at some point a `#[property(getter, setter = setIvar)]` attribute for generating Objective-C getter and setter methods. This fixes #788. A downside is that deriving `Default` is no longer possible, which means that some `init` methods are a bit longer, but we should really solve that by allowing some sort of `Default` on the class itself, see #267.
1 parent f906f40 commit 78d1cf6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+937
-475
lines changed

crates/objc2/CHANGELOG.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,88 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88

99
### Added
1010
* Implement `Encode` for i128 and u128, allowing using them in more FFI situations.
11+
* Added `Ivars<T>` type alias for more easily accessing `<T as DefineClass>::Ivars`.
1112

1213
## Changed
1314
* **BREAKING** (very slightly): `define_class!` now rejects non-static and
1415
non-unique class names.
16+
* **BREAKING**: Changed syntax for `define_class!` ivars (instance variables).
17+
18+
Note in particular the new `Ivars::<Self> { ... }` syntax, when
19+
initializing, and that you no longer need `.ivars()` when accessing.
20+
21+
```rust
22+
//
23+
// Before
24+
//
25+
26+
use objc2::rc::Retained;
27+
use objc2::runtime::NSObject;
28+
use objc2::{define_class, msg_send, AnyThread, DefinedClass};
29+
30+
struct MyIvars {
31+
x: i32,
32+
y: i32,
33+
}
34+
35+
define_class!(
36+
#[unsafe(super(NSObject))]
37+
#[name = "MyObject"]
38+
#[ivars = MyIvars]
39+
struct MyObject;
40+
41+
impl MyObject {
42+
// ...
43+
}
44+
);
45+
46+
impl MyObject {
47+
fn new() -> Retained<Self> {
48+
let this = Self::alloc().set_ivars(MyIvars { x: 10, y: 20 });
49+
unsafe { msg_send![super(this), init] }
50+
}
51+
}
52+
53+
let obj = MyObject::new();
54+
assert_eq!(obj.ivars().x, 10);
55+
assert_eq!(obj.ivars().y, 20);
56+
57+
//
58+
// After
59+
//
60+
61+
use objc2::rc::Retained;
62+
use objc2::runtime::NSObject;
63+
// Import `Ivars` instead of `DefinedClass`.
64+
use objc2::{define_class, msg_send, AnyThread, Ivars};
65+
66+
define_class!(
67+
#[unsafe(super(NSObject))]
68+
#[name = "MyObject"]
69+
struct MyObject {
70+
// Ivars moved into `define_class!` macro.
71+
x: i32,
72+
y: i32,
73+
}
74+
75+
impl MyObject {
76+
// ...
77+
}
78+
);
79+
80+
impl MyObject {
81+
fn new() -> Retained<Self> {
82+
// Use `Ivars::<Self>` to refer to all the instance variables.
83+
let this = Self::alloc().set_ivars(Ivars::<Self> { x: 10, y: 20 });
84+
unsafe { msg_send![super(this), init] }
85+
}
86+
}
87+
88+
let obj = MyObject::new();
89+
assert_eq!(*obj.x(), 10); // No longer need `.ivars()`
90+
assert_eq!(*obj.y(), 20);
91+
```
92+
* Improved the derived `Debug` impl for classes defined with `define_class!`.
1593

1694
## Fixed
1795
* Fixed encoding check when using SIMD types in signatures.

crates/objc2/src/__macros/attribute_helpers.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,6 @@ macro_rules! __extract_attributes {
547547
// The contents of the `name` attribute, if any.
548548
// ($($name:expr)?)
549549
//
550-
// The contents of the `ivars` attribute, if any.
551-
// ($($ivars:path)?)
552-
//
553550
// The list of paths in all `derive` attributes.
554551
// ($($derives:path),*)
555552
//
@@ -566,7 +563,6 @@ macro_rules! __extract_attributes {
566563
() // superclasses
567564
() // thread_kind
568565
() // name
569-
() // ivars
570566
() // derive
571567
() // attr_item
572568
() // attr_impl
@@ -588,7 +584,6 @@ macro_rules! __extract_attributes_inner {
588584
($($superclasses:tt)*)
589585
($($thread_kind:tt)*)
590586
($($name:tt)*)
591-
($($ivars:tt)*)
592587
($($derives:tt)*)
593588
($($attr_item:tt)*)
594589
($($attr_impl:tt)*)
@@ -604,7 +599,6 @@ macro_rules! __extract_attributes_inner {
604599
($($superclasses)*)
605600
($($thread_kind)*)
606601
($($name)*)
607-
($($ivars)*)
608602
($($derives)*)
609603
($($attr_item)*)
610604
($($attr_impl)*)
@@ -621,7 +615,6 @@ macro_rules! __extract_attributes_inner {
621615
($($superclasses:tt)*)
622616
($($thread_kind:tt)*)
623617
($($name:tt)*)
624-
($($ivars:tt)*)
625618
($($derives:tt)*)
626619
($($attr_item:tt)*)
627620
($($attr_impl:tt)*)
@@ -636,7 +629,6 @@ macro_rules! __extract_attributes_inner {
636629
(unsafe $($parsed)*)
637630
($($thread_kind)*)
638631
($($name)*)
639-
($($ivars)*)
640632
($($derives)*)
641633
($($attr_item)*)
642634
($($attr_impl)*)
@@ -655,7 +647,6 @@ macro_rules! __extract_attributes_inner {
655647
($($superclasses:tt)*)
656648
($($thread_kind:tt)*)
657649
($($name:tt)*)
658-
($($ivars:tt)*)
659650
($($derives:tt)*)
660651
($($attr_item:tt)*)
661652
($($attr_impl:tt)*)
@@ -670,7 +661,6 @@ macro_rules! __extract_attributes_inner {
670661
(unsafe $parsed)
671662
($($thread_kind)*)
672663
($($name)*)
673-
($($ivars)*)
674664
($($derives)*)
675665
($($attr_item)*)
676666
($($attr_impl)*)
@@ -690,7 +680,6 @@ macro_rules! __extract_attributes_inner {
690680
($($superclasses:tt)*)
691681
($($thread_kind:tt)*)
692682
($($name:tt)*)
693-
($($ivars:tt)*)
694683
($($derives:tt)*)
695684
($($attr_item:tt)*)
696685
($($attr_impl:tt)*)
@@ -705,7 +694,6 @@ macro_rules! __extract_attributes_inner {
705694
(safe $($parsed)*)
706695
($($thread_kind)*)
707696
($($name)*)
708-
($($ivars)*)
709697
($($derives)*)
710698
($($attr_item)*)
711699
($($attr_impl)*)
@@ -724,7 +712,6 @@ macro_rules! __extract_attributes_inner {
724712
($($superclasses:tt)*)
725713
($($thread_kind:tt)*)
726714
($($name:tt)*)
727-
($($ivars:tt)*)
728715
($($derives:tt)*)
729716
($($attr_item:tt)*)
730717
($($attr_impl:tt)*)
@@ -739,7 +726,6 @@ macro_rules! __extract_attributes_inner {
739726
(safe $parsed)
740727
($($thread_kind)*)
741728
($($name)*)
742-
($($ivars)*)
743729
($($derives)*)
744730
($($attr_item)*)
745731
($($attr_impl)*)
@@ -759,7 +745,6 @@ macro_rules! __extract_attributes_inner {
759745
($($superclasses:tt)*)
760746
($($thread_kind:tt)*)
761747
($($name:tt)*)
762-
($($ivars:tt)*)
763748
($($derives:tt)*)
764749
($($attr_item:tt)*)
765750
($($attr_impl:tt)*)
@@ -774,7 +759,6 @@ macro_rules! __extract_attributes_inner {
774759
($($superclasses)*)
775760
($($parsed)+)
776761
($($name)*)
777-
($($ivars)*)
778762
($($derives)*)
779763
($($attr_item)*)
780764
($($attr_impl)*)
@@ -794,7 +778,6 @@ macro_rules! __extract_attributes_inner {
794778
($($superclasses:tt)*)
795779
($($thread_kind:tt)*)
796780
($($name:tt)*)
797-
($($ivars:tt)*)
798781
($($derives:tt)*)
799782
($($attr_item:tt)*)
800783
($($attr_impl:tt)*)
@@ -809,7 +792,6 @@ macro_rules! __extract_attributes_inner {
809792
($($superclasses)*)
810793
($($thread_kind)*)
811794
($($parsed)+)
812-
($($ivars)*)
813795
($($derives)*)
814796
($($attr_item)*)
815797
($($attr_impl)*)
@@ -819,7 +801,7 @@ macro_rules! __extract_attributes_inner {
819801
}
820802
};
821803

822-
// `ivars = ...`
804+
// `ivars = ...` (old syntax, removed)
823805
{
824806
(
825807
#[ivars = $($parsed:tt)+]
@@ -829,22 +811,29 @@ macro_rules! __extract_attributes_inner {
829811
($($superclasses:tt)*)
830812
($($thread_kind:tt)*)
831813
($($name:tt)*)
832-
($($ivars:tt)*)
833814
($($derives:tt)*)
834815
($($attr_item:tt)*)
835816
($($attr_impl:tt)*)
836817

837818
($out_macro:path)
838819
$($out_args:tt)*
839820
} => {
840-
$crate::__handle_duplicate!("ivars"; $($ivars)*);
821+
$crate::__macros::compile_error!(
822+
$crate::__macros::concat!(
823+
"the syntax for specifying instance variables has changed, move the ivars to a field in the struct instead\n",
824+
// For better support in rust-analyzer.
825+
"#[ivars = ",
826+
$crate::__macros::stringify!($($parsed)+),
827+
"] -> ivars: ",
828+
$crate::__macros::stringify!($($parsed)+),
829+
)
830+
);
841831
$crate::__extract_attributes_inner! {
842832
($($rest)*)
843833

844834
($($superclasses)*)
845835
($($thread_kind)*)
846836
($($name)*)
847-
($($parsed)+)
848837
($($derives)*)
849838
($($attr_item)*)
850839
($($attr_impl)*)
@@ -864,7 +853,6 @@ macro_rules! __extract_attributes_inner {
864853
($($superclasses:tt)*)
865854
($($thread_kind:tt)*)
866855
($($name:tt)*)
867-
($($ivars:tt)*)
868856
($($derives:tt)*)
869857
($($attr_item:tt)*)
870858
($($attr_impl:tt)*)
@@ -878,7 +866,6 @@ macro_rules! __extract_attributes_inner {
878866
($($superclasses)*)
879867
($($thread_kind)*)
880868
($($name)*)
881-
($($ivars)*)
882869
// Combine all #[derive(...)] into one list.
883870
($($derives)*, $($parsed)*)
884871
($($attr_item)*)
@@ -899,7 +886,6 @@ macro_rules! __extract_attributes_inner {
899886
($($superclasses:tt)*)
900887
($($thread_kind:tt)*)
901888
($($name:tt)*)
902-
($($ivars:tt)*)
903889
($($derives:tt)*)
904890
($($attr_item:tt)*)
905891
($($attr_impl:tt)*)
@@ -913,7 +899,6 @@ macro_rules! __extract_attributes_inner {
913899
($($superclasses)*)
914900
($($thread_kind)*)
915901
($($name)*)
916-
($($ivars)*)
917902
($($derives)*)
918903
(
919904
$($attr_item)*
@@ -940,7 +925,6 @@ macro_rules! __extract_attributes_inner {
940925
($($superclasses:tt)*)
941926
($($thread_kind:tt)*)
942927
($($name:tt)*)
943-
($($ivars:tt)*)
944928
($($derives:tt)*)
945929
($($attr_item:tt)*)
946930
($($attr_impl:tt)*)
@@ -954,7 +938,6 @@ macro_rules! __extract_attributes_inner {
954938
($($superclasses)*)
955939
($($thread_kind)*)
956940
($($name)*)
957-
($($ivars)*)
958941
($($derives)*)
959942
(
960943
$($attr_item)*
@@ -982,7 +965,6 @@ macro_rules! __extract_attributes_inner {
982965
($($superclasses:tt)*)
983966
($($thread_kind:tt)*)
984967
($($name:tt)*)
985-
($($ivars:tt)*)
986968
($($derives:tt)*)
987969
($($attr_item:tt)*)
988970
($($attr_impl:tt)*)
@@ -996,7 +978,6 @@ macro_rules! __extract_attributes_inner {
996978
($($superclasses)*)
997979
($($thread_kind)*)
998980
($($name)*)
999-
($($ivars)*)
1000981
($($derives)*)
1001982
// Pass all other attributes onwards to the struct.
1002983
(

0 commit comments

Comments
 (0)