2011-08-16 6 views
39

En una aplicación de piano, estoy asignando las coordenadas de las teclas negras. Aquí está la línea de código que causa el error."La expresión no es asignable" - Problema que asigna flotación como suma de otros dos flotantes en xCode?

'blackKey' y '' son ambos whiteKey CustomViews

blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width); 
+0

Tenga en cuenta que 'whiteKey.frame.origin.x + whiteKey.frame.size.width' es lo mismo que' CGRectGetMaxX (whiteKey.frame) '. – ThomasW

Respuesta

81

Las otras respuestas no explican exactamente lo que está pasando aquí, por lo que este es el problema básico:

Cuando se escribe blackKey.center.x, la blackKey.center y center.x tanto se parecen a los accesos miembro de estructura, pero' en realidad son cosas completamente diferentes. blackKey.center es un acceso a la propiedad, que se deshace a algo así como [blackKey center], que a su vez desagua a algo así como objc_msgSend(blackKey, @selector(center)). No puede modificar el valor de retorno de una función, como objc_msgSend(blackKey, @selector(center)).x = 2 - simplemente no es significativo, porque el valor de retorno no es almacenado en cualquier lugar significativo.

Por lo tanto, si desea modificar la estructura, debe almacenar el valor de retorno de la propiedad en una variable, modificar la variable y luego establecer la propiedad en el nuevo valor.

+0

Podemos establecer 'anObject.anNonStructProperty.anProperty = someValue' ¿verdad? ¿Cómo se dice que no podemos modificar el valor de retorno de una función? ¿Puede usted explicar por favor? – EmptyStack

+4

@EmptyStack: Cuando escribes 'anObject.someProperty = something', eso no es equivalente a' [anObject someProperty] = something' - en cambio, es equivalente a '[anObject setSomeProperty: something]'. Está enviando un mensaje al objeto para llamar a un método setter. No está asignando el valor de retorno del método. La apariencia de una tarea es simplemente azúcar sintáctica, al igual que la apariencia de un miembro de acceso es azúcar sintáctica para un método getter. – Chuck

+0

Todavía no entiendo claramente. Incluso en su respuesta, 'blackKey.center' internamente llama a' objc_msgSend (blackKey, @selector (setCenter :)) 'y no a' objc_msgSend (blackKey, @selector (center)) 'right? – Adithya

10
blackKey.center = CGPointMake (whiteKey.frame.origin.x + whiteKey.frame.size.width, blackKey.center.y); 

Una forma de hacerlo.

19

No se puede cambiar directamente el valor x de CGPoint (o cualquier valor de una estructura) como ese, si es una propiedad de un objeto. Haz algo como lo siguiente.

CGPoint _center = blackKey.center; 
_center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width); 
blackKey.center = _center; 
0

una alternativa el uso de macros:

#define CGPOINT_SETX(point, x_value) { \ 
    CGPoint tempPoint = point;   \ 
    tempPoint.x = (x_value);   \ 
    point = tempPoint;     \ 
} 

#define CGPOINT_SETY(point, y_value) { \ 
    CGPoint tempPoint = point;   \ 
    tempPoint.y = (y_value);   \ 
    point = tempPoint;     \ 
} 

CGPOINT_SETX(blackKey.center, whiteKey.frame.origin.x + whiteKey.frame.size.width); 

o ligeramente más simples:

CGPOINT_SETX(blackKey.center, CGRectGetMaxX(whiteKey.frame)); 
+1

¿Realmente necesitas el 'do ... while (0)'? ¿No es el alcance del bloque '{...}' suficiente para declarar las variables de temperatura (sin colisiones de nombre con algo que está justo afuera), y las instrucciones se ejecutan exactamente una vez? –

+0

@NicolasMiari He estado usando 'do ... while (0)' durante tanto tiempo que no me di cuenta de que los bloques '{...}' funcionan bien. Gracias. Simplificando – ThomasW

+1

El razonamiento para el 'do ... while (0)' está aquí: http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-cc-macros Para mi caso no es necesario, pero hay casos en que sí lo es. – ThomasW

Cuestiones relacionadas