Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C struct definition and modification gives error 'Expression not assignable'?

I have been reading other similar questions but those solutions either don't fit our don't solve the problem I have in my hand. My code is actually quite simple, I don't know how I should do what I want. Ok:

In .h file I have:

struct MyState{
    float quantizer;
    BOOL isOpen;
};

@interface ... {
    ...
    struct MyState myState;
}

@property (nonatomic,assign) struct MyState myState;

And in .m file, I have write and reads such as:

@synthesize myState

...
self.myState.isOpen = TRUE;
if(self.myState.isOpen)
    self.myState.quantizer = myQuantizerValue;

Now, XCode won't accept accessing with '.' operator. It says 'Expression is not assignable'. I tried changing myState to a pointer and converted my read/write's to user '->' operator like:

self.myState->isOpen = TRUE;

It then gives a runtime error on the assignment. What should I do to access and modify these properties in a simple way? I wanted to use a struct constructor just to avoid declaring and synthesizing separate variables for each property in MyStruct.

like image 989
batilc Avatar asked Dec 25 '22 22:12

batilc


1 Answers

This is the same reason why you can't assign into the size of a view's frame property. It's a limitation of Objective-C. See the discussion of this issue at the end of this section of my book. As I explain there, you have to fetch the struct property value into a variable, change the member of the struct, and assign back into the property:

struct MyState s = self.myState;
s.isOpen = YES;
self.myState = s;

Basically this is because the "dot" in self.myState is completely different from the "dot" in myState.isOpen. The first one is an Objective-C call to the myState method, and returns a struct. The second one is a C access to a struct member.

The alternative is simply not to use an Objective-C property in the first place: just access the instance variable directly:

self->myState.isOpen = YES;

But of course you can't do that from some other class without making this instance variable public...

like image 186
matt Avatar answered Dec 28 '22 09:12

matt