如何检查CGPoint是否已被初始化?

21

我想最初将一个CGPoint属性设置为特定的点(屏幕中央)。其他方法可能随后希望更改此属性。我的想法是在getter中初始化它,如果为空,则无效参数类型“struct CGPoint”到单元表达式。我还尝试使用if属性==nil或0,但没有成功。

有什么想法吗?

-(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;
< p > } < /p >
6个回答

31
CGPoint是一个结构体,因此您无法将其设置为nil或NULL(它不是指针)。从某种意义上说,实际上没有“未初始化”的状态。也许您可以使用{0.0,0.0}来表示未设置的CGPoint,但这也是一个有效的坐标。或者,您可以使用负的xy值来标记“未初始化”的点,因为负值不能是有效的绘图点,但这也有点像欺骗操作。

您最好的选择可能是以下两项之一:

  1. 将属性存储为指向CGPoint的指针。当未初始化时,此值可以设置为NULL。当然,您必须担心mallocfree该值。
  2. CGPoint与名为pointInitializedBOOL一起存储,最初设置为NO,但在点初始化后设置为YES。您甚至可以将其封装在一个结构体中:
  3. struct {
        CGPoint point;
        BOOL initialized;
    } pointData;
    

4
我更喜欢这个答案,因为 {0.0, 0.0} 是一个真正存在且有效的坐标。把它作为一个零点可能会破坏你程序的逻辑。 - Stas
1
将CGPoint设置为-1,-1对我来说似乎比其他建议更不像黑客。添加单独的布尔变量似乎违反了单一真相点 - 如果没有在变量状态更改时更新它,它将给出错误的结果。 - arlomedia
也许这是可怕的编程方式,但如果你非常需要,你可以将{NAN,NAN}作为坐标传递给你的CGPoint。 - user3720516

22
更简单的方法是将_graphOrigin初始化为CGRectZero,并将您的if语句更改为以下内容:
if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) {  

}

11

CGPoint没有未初始化的状态。但是,如果您将点(0,0)视为未初始化,则可以使用

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

这段代码之所以能正常工作,是因为在Objective-C实例初始化的时候,它的所有实例变量被清除为零位,而在CGFloat表示中,这个值就是0.0。

(注意:即使操作数是CGFloat,使用==也是可行的,因为我们想要与一个精确的位模式进行比较(忽略-0的问题))


10
(0, 0) 是一个有效的坐标。 - jjeaton

5

由于CGPointZero(0,0)和您给定的任何其他点值可能存在于您的上下文中,因此您可能希望使用以下方法将NSValue初始化为您的点:

NSValue *pointVal = [NSValue valueWithCGPoint:point];

你可以根据某些条件进行操作,然后在之后检测NSValue是否为nil。 如果需要,还可以将NSValue添加到数组中,从而可以拥有一个点的数组。
要在之后获取该点,只需使用:
```objective-c [myNSValue pointValue]; ```
CGPoint point = [pointVal CGPointValue]; 

这个解决方案非常适用于检查“point”结构是否存在的IF语句。您可以检查pointVal是否为nil(... if(pointVal)...),而使用point则不行(... if(point)...会导致“无效操作数”错误)。 - GlennRay

1
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

0
创建两个CGPoint属性,这样它们都是“未初始化”的。设置其中一个并使用第二个来检查它们是否相等。
@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

我不知道你是否认为这种方法有些hackish。我知道你的问题已经得到了回答,但我也曾经遇到过类似的困境,直到我想到了这个方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接