"Expression is not assignable" -- Problem assigning float as sum of two other floats in Xcode?
Solution 1
The other answers don't exactly explain what's going on here, so this is the basic problem:
When you write blackKey.center.x
, the blackKey.center
and center.x
both look like struct member accesses, but they're actually completely different things. blackKey.center
is a property access, which desugars to something like [blackKey center]
, which in turn desugars to something like objc_msgSend(blackKey, @selector(center))
. You can't modify the return value of a function, like objc_msgSend(blackKey, @selector(center)).x = 2
— it just isn't meaningful, because the return value isn't stored anywhere meaningful.
So if you want to modify the struct, you have to store the return value of the property in a variable, modify the variable, and then set the property to the new value.
Solution 2
You can not directly change the x
value of a CGPoint
(or any value of a struct) like that, if it is an property of an object. Do something like the following.
CGPoint _center = blackKey.center;
_center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
blackKey.center = _center;
Solution 3
blackKey.center = CGPointMake ( whiteKey.frame.origin.x + whiteKey.frame.size.width, blackKey.center.y);
One way of doing it.
Mahir
Updated on July 09, 2022Comments
-
Mahir almost 2 years
In a piano app, I'm assigning the coordinates of the black keys. Here is the line of code causing the error.
'blackKey' and 'whiteKey' are both customViews
blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
-
EmptyStack over 12 yearsWe can set
anObject.anNonStructProperty.anProperty = someValue
right? How do you say that we can not modify the return value of a function. Can you please explain? -
Chuck over 12 years@EmptyStack: When you write
anObject.someProperty = something
, that is not equivalent to[anObject someProperty] = something
— instead, it's equivalent to[anObject setSomeProperty:something]
. You're sending a message to the object to call a setter method. You aren't assigning to the method's return value. The appearance of an assignment is just syntactic sugar, just like the appearance of a member access is syntactic sugar for a getter method. -
Adithya almost 10 yearsI still don't get it clearly. Even in your answer,
blackKey.center
internally callsobjc_msgSend(blackKey, @selector(setCenter:))
and notobjc_msgSend(blackKey, @selector(center))
right? -
Chuck almost 10 years@Adithya: No. If you think
blackKey.center
callssetCenter:
, then what do you imagine the argument is?[blackKey setCenter: ?????]
. It's just[blackKey center]
. -
Nicolas Miari over 8 yearsDo you really need the
do ... while(0)
? Isn't the block scope{ ... }
enough to declare the temp variables (without potentially name-colliding with something just outside), and have the statements within executed exactly once? -
ThomasW over 8 years@NicolasMiari I've been using
do ... while(0)
for such a long time that I didn't realize that{...}
blocks work just fine. Thanks. Simplifying. -
ThomasW over 8 yearsThe reasoning for the
do ... while(0)
is here: stackoverflow.com/questions/154136/… For my case it isn't necessary, but there are cases where it is.