2012-01-19 3 views
17

Je voudrais initialement définir une propriété CGPoint à un point particulier (milieu de l'écran). D'autres méthodes peuvent ensuite souhaiter modifier cette propriété. Mes pensées étaient de l'initialiser si vide dans le getter, mais je reçois le type d'argument non valide 'struct CGPoint' en expression unaire. J'ai aussi essayé d'utiliser if property == nil ou 0 mais pas de joie.Comment vérifier si un CGPoint a été initialisé?

Des pensées?

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

}

Répondre

29

A CGPoint est un struct, donc vous ne pouvez pas le mettre à zéro ou NULL (ce n'est pas un pointeur). Dans un sens, il n'y a vraiment pas d'état "non initialisé". Peut-être que vous pourriez utiliser {0.0, 0.0} pour désigner un CGPoint non défini, mais c'est aussi une coordonnée valide. Ou vous pouvez utiliser des valeurs négatives x et y pour marquer un point «non initialisé», car les valeurs négatives ne peuvent pas être des points de dessin valides, mais c'est aussi un peu un hack.

probablement votre meilleur pari est de faire l'une des deux choses:

  1. magasin la propriété comme un pointeur vers un CGPoint. Cette valeur peut être définie sur NULL lorsqu'elle n'est pas initialisée. Bien sûr, vous devez vous soucier de malloc ing et free en valeur.
  2. magasin le CGPoint à côté d'un BOOL appelé pointInitialized ou somesuch, initialement à NO, mais mis à YES une fois que le point a été initialisé. Vous pouvez même WRAP dans une struct:

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

J'aime beaucoup mieux cette réponse, car ** {0.0, 0.0} ** est une coordonnée vraiment existante et valide. L'utiliser comme un point nul pourrait casser votre logique de programme. – Stas

+1

Mettre le CGPoint à -1, -1 me semble moins hackish que les autres suggestions. L'ajout d'une variable booléenne distincte ressemble à une violation de point de vérité unique - elle donnera un résultat incorrect si elle n'est pas mise à jour chaque fois que l'état de la variable est modifié. – arlomedia

+0

Programmation probablement horrible, mais si vous êtes désespéré, vous pouvez toujours passer {NAN, NAN} comme coordonnées à votre CGPoint. – Tommyixi

10

CGPoint ne dispose pas d'un état non initialisé. Cependant, si l'on considère le point (0, 0) comme non initialisée, vous pouvez utiliser

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

Cela fonctionne parce que quand une instance Objective-C est initialisé, toutes ses Ivar sont effacées aux bits de zéro, qui, dans le La représentation CGFloat est 0.0.

(Note: Le == est bien ici, même si les opérandes sont CGFloat parce que nous voulons comparer avec le un motif binaire exact (en ignorant la question de -0))

+0

fonctionne très bien, merci! – Alan

+9

(0, 0) est une coordonnée valide – jjeaton

+0

vrai que @jjeaton – abbood

21

Une façon plus facile serait d'initialiser _graphOrigin à CGRectZero et changer votre instruction if pour cela:

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) { 

} 
0

Créer deux propriétés CGPoint, de cette façon, ils sont tous les deux "non initialisés". Définissez l'un d'entre eux et utilisez le second pour vérifier s'ils sont égaux ou non.

@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 vous considérez que cette façon de procéder est hackish. Et je sais que vous avez déjà répondu à votre question, mais j'avais le même dilemme jusqu'à ce que j'y pense.

5

Depuis CGPointZero (0,0) et toute autre valeur que vous donnez un point peut exister dans votre contexte vous pouvez initialiser un NSValue avec votre point à l'aide:

NSValue *pointVal = [NSValue valueWithCGPoint:point]; 

Vous pouvez le faire en fonction de certaines conditions, puis plus tard tester le NSValue pour néant. NSValue peut également être ajouté à un tableau qui vous permettrait d'avoir un tableau de points si vous en avez besoin.

Pour obtenir le point plus tard utilisez simplement:

CGPoint point = [pointVal CGPointValue]; 
+0

Cette solution est très utile pour une instruction IF vérifiant si la structure 'point' existe. Vous pouvez vérifier si pointVal est nul (... if (pointVal) ...), ce que vous ne pouvez pas faire avec le point (... si (point) ... vous donne une erreur 'opérande invalide'). – 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 
Questions connexes