2012-01-19 17 views
17

Me gustaría establecer inicialmente una propiedad CGPoint en un punto particular (centro de la pantalla). Otros métodos pueden subsecuentemente desear cambiar esta propiedad. Mis pensamientos fueron inicializarlo si está vacío en el getter, pero obtengo el mensaje de argumento inválido tipo 'struct CGPoint' en expresión unaria. También intenté usar if property == nil o 0 pero no joy.¿Cómo verifico si un CGPoint se ha inicializado?

¿Alguna idea?

-(CGPoint)graphOrigin 
{ 
    // initialise to centre of screen if has not been set 
    if(!_graphOrigin) // this expression is causing the problem 
    { 
     CGPoint origin = CGPointMake(self.bounds.origin.x + self.bounds.size.width/2, self.bounds.origin.y + self.bounds.size.height/2); 

     _graphOrigin = origin; 
    } 

return _graphOrigin; 

}

Respuesta

29

Un CGPoint es una estructura, por lo que no puede establecerlo en cero o NULL (no es un puntero). En cierto sentido, realmente no hay un estado "no inicializado". Quizás podría usar {0.0, 0.0} para designar un desarmado CGPoint, pero eso también es una coordenada válida. O puede usar los valores x y y negativos para marcar un punto "no inicializado", ya que los valores negativos no pueden ser puntos de dibujo válidos, pero eso también es un truco.

Probablemente la mejor opción es hacer una de dos cosas:

  1. tienda de la propiedad como un puntero a una CGPoint. Este valor se puede establecer en NULL cuando no se inicializa. Por supuesto, debe preocuparse por malloc ing y free ing el valor.
  2. tienda del CGPoint junto a un BOOL llamada pointInitialized o algo por el estilo, establece inicialmente en NO, pero ajustado a YES una vez que el punto se ha inicializado. Incluso puede envolver que en una estructura:

    struct { 
        CGPoint point; 
        BOOL initialized; 
    } pointData; 
    
+3

Me gusta esta respuesta mucho más, porque ** {0.0, 0.0} ** es una coordenada realmente existente y válida. Usar eso como un punto nulo puede romper la lógica de tu programa. – Stas

+1

Configurar el CGPoint en -1, -1 me parece menos hackoso que las otras sugerencias. Agregar una variable booleana separada parece ser una violación de Punto único de la verdad: dará un resultado incorrecto si no se actualiza cada vez que se cambia el estado de la variable. – arlomedia

+0

Programación probablemente horrible, pero si estás desesperado, siempre puedes pasar {NAN, NAN} como coordenadas a tu CGPoint. – Tommyixi

10

CGPoint no tiene un estado no inicializado. Sin embargo, si se tiene en cuenta el punto (0, 0) como no inicializado, se puede usar

if (_graphOrigin.x == 0 && _graphOrigin.y == 0) 
{ 
    ... 

Esto funciona porque cuando se inicia una instancia de Objective-C, toda su Ivar se borran a los bits de cero, lo que en el La representación de CGFloat es 0.0.

(Nota: El == está bien aquí, incluso si los operandos son CGFloat porque queremos comparar con el de un patrón de bits exacta (ignorando el tema de -0))

+0

funciona bien, gracias! – Alan

+9

(0, 0) es una coordenada válida – jjeaton

+0

cierto que @jjeaton – abbood

21

Una forma más fácil sería para inicializar _graphOrigin a CGRectZero y cambiar su sentencia if para esto:

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) { 

} 
0

Cree dos propiedades CGPoint, de esa manera ambos son "no inicializados". Establezca uno de ellos y use el segundo para verificar si son iguales o no.

@interface ClassName() 

@property (nonatomic) CGPoint point1; 
@property (nonatomic) CGPoint point2; 

@end 

@implementation ClassName 

self.point1 = CGPointMake(69.0f, 180.0f); //arbitrary numbers 

    //if not equal, then if statement proceeds 
if (!CGPointEqualToPoint(self.point1, self.point2) { 
    //your code here 
} 

@end 

idk si lo considera de esta manera hacker sin embargo. Y sé que su pregunta ya fue respondida, pero tuve el mismo dilema hasta que pensé en esto.

5

Desde CGPointZero (0,0) y cualquier otro valor que da un punto pueden existir en su contexto es posible que desee inicializar un NSValue con su punto usando:

NSValue *pointVal = [NSValue valueWithCGPoint:point]; 

usted puede hacer esto sobre la base de alguna condición y luego prueba NSValue por nil. NSValue también se puede agregar a una matriz que le permite tener una variedad de puntos en caso de que lo necesite.

para obtener el punto más adelante simplemente utilizar:

CGPoint point = [pointVal CGPointValue]; 
+0

Esta solución es muy útil para una declaración IF que verifica si existe la estructura 'point'. Puede verificar si pointVal es nil (... if (pointVal) ...), lo cual no se puede hacer con el punto (... if (point) ... le da un error de 'operando inválido'). – GlennRay

0
static CGPoint kInvalidPoint = {.x = NSIntegerMax, .y = NSIntegerMax}; 

@implementation MyClass 

- init() 
{ 
    self = [super init]; 
    if (self) { 
     _oldPoint = kInvalidPoint; 
    } 
    return self; 
} 

- (void)foo 
{ 
    if (CGPointEqualToPoint(self.oldPoint, kInvalidPoint)) { 
     // Invalid point. 
     return; 
    } 
} 

@end 
Cuestiones relacionadas