2012-01-19 20 views
17

Vorrei inizialmente impostare una proprietà CGPoint su un punto particolare (al centro dello schermo). Altri metodi potrebbero successivamente desiderare di cambiare questa proprietà. I miei pensieri erano di inizializzarlo se vuoto nel getter, ma ottengo il messaggio tipo argomento non valido 'struct CGPoint' all'espressione unaria. Ho anche provato ad usare if property == nil o 0 ma nessuna gioia.Come posso verificare se un CGPoint è stato inizializzato?

Qualche 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; 

}

risposta

29

Un CGPoint è una struttura, quindi non puoi impostarlo su nil o NULL (non è un puntatore). In un certo senso, non c'è davvero uno stato "non inizializzato". Forse potresti usare {0.0, 0.0} per designare unset CGPoint, ma questa è anche una coordinata valida. Oppure è possibile utilizzare valori negativi x e per contrassegnare un punto "non inizializzato", poiché i valori negativi non possono essere punti di disegno validi, ma anche questo è un po 'un attacco.

probabilmente la soluzione migliore è quella di fare una delle due cose:

  1. Conservare la proprietà come un puntatore ad un CGPoint. Questo valore può essere impostato su NULL quando non inizializzato. Naturalmente, è necessario preoccuparsi di malloc ing e free il valore.
  2. Conservare il CGPoint a fianco di un BOOL chiamato pointInitialized o somesuch, inizialmente impostata su NO, ma impostato YES una volta che il punto è stato inizializzato. Si può anche avvolgere che in una struct:

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

Mi piace molto questa risposta, perché ** {0.0, 0.0} ** è una coordinata realmente esistente e valida. Usarlo come punto nullo potrebbe infrangere la logica del tuo programma. – Stas

+1

Impostando il CGPoint su -1, -1 mi sembra meno logico degli altri suggerimenti. L'aggiunta di una variabile booleana separata sembra una violazione di un singolo punto di verità - fornirà un risultato errato se non viene aggiornato ogni volta che lo stato della variabile viene modificato. – arlomedia

+0

Programmazione probabilmente orribile, ma se sei disperato potresti sempre passare {NAN, NAN} come coordinate al tuo CGPoint. – Tommyixi

10

CGPoint non ha uno stato non inizializzato. Tuttavia, se si considera il punto (0, 0) come non inizializzato, è possibile utilizzare

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

Questo funziona perché quando un'istanza Objective-C è inizializzato, tutto il suo ivar vengono cancellate a pezzi di zero, che nel La rappresentazione di CGFloat è 0.0.

(Nota: Il == è bene qui, anche se gli operandi sono CGFloat perché vogliamo confrontare con il modello esatto di un po '(ignorando la questione della -0))

+0

funziona bene, grazie! – Alan

+9

(0, 0) è una coordinata valida – jjeaton

+0

true che @jjeaton – abbood

21

Un modo più semplice sarebbe quella di inizializzare _graphOrigin a CGRectZero e cambiare la vostra istruzione if per questo:

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) { 

} 
0

Creare due proprietà CGPoint, in questo modo sono entrambi "non inizializzati". Impostane uno e usa il secondo per verificare se sono uguali o meno.

@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 se in questo modo si considererebbe hackish. E so che alla tua domanda è già stata data una risposta, ma ho avuto lo stesso dilemma fino a quando ho pensato a questo.

5

Dal CGPointZero (0,0) e qualsiasi altro valore si dà un punto possono esistere nel vostro contesto si consiglia di inizializzare un NSValue con il punto di utilizzo:

NSValue *pointVal = [NSValue valueWithCGPoint:point]; 

si potrebbe fare questo sulla base di alcune condizioni e successivamente testare NSValue per zero. NSValue può anche essere aggiunto a un array che consente di disporre di una serie di punti se necessario.

per ottenere il punto in seguito utilizzare semplicemente:

CGPoint point = [pointVal CGPointValue]; 
+0

Questa soluzione è molto utile per un'istruzione IF che verifica se la struttura 'punto' esiste. Puoi verificare se pointVal è nullo (... if (pointVal) ...), che non puoi fare con point (... if (point) ... ti dà un errore 'operando non valido'). – 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 
Problemi correlati