Подтвердить что ты не робот

Как проверить, был ли CGPoint инициализирован?

Я хотел бы сначала установить свойство CGPoint в определенную точку (в середине экрана). Другие методы могут впоследствии пожелать изменить это свойство. Мои мысли состояли в том, чтобы инициализировать его, если он пуст в getter, но я получаю сообщение недопустимым аргументом типа struct CGPoint для унарного выражения. Я также попытался использовать if property == 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;

}

4b9b3361

Ответ 1

A CGPoint - это структура, поэтому вы не можете установить ее в nil или NULL (это не указатель). В некотором смысле, действительно нет "неинициализированного" состояния. Возможно, вы могли бы использовать {0.0, 0.0} для обозначения unset CGPoint, но это также действительная координата. Или вы можете использовать отрицательные значения x и y для отметки "неинициализированной" точки, так как отрицательные значения не могут быть действительными точками рисования, но это тоже немного взломать.

Наверное, лучше всего сделать одну из двух вещей:

  • Сохраните свойство как указатель на CGPoint. Это значение может быть установлено на NULL при неинициализации. Конечно, вам нужно беспокоиться о malloc ing и free значения.
  • Сохраните CGPoint вместе с BOOL, называемым pointInitialized или somesuch, изначально установленным на NO, но установите значение YES после того, как точка была инициализирована. Вы можете даже обернуть это в структуру:

    struct {
        CGPoint point;
        BOOL initialized;
    } pointData;
    

Ответ 2

Более простой способ - инициализировать _graphOrigin для CGRectZero и изменить для этого оператор if:

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) {  

}

Ответ 3

CGPoint не имеет неинициализированного состояния. Однако, если вы считаете точку (0, 0) неинициализированной, вы можете использовать

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

Это работает, потому что, когда инициализируется экземпляр Objective-C, все его ivar очищаются до бит из нуля, который в представлении CGFloat равен 0.0.

(Примечание: == здесь отлично, даже если операнды являются CGFloat, потому что мы хотим сравнить с точным битовым шаблоном (игнорируя проблему -0))

Ответ 4

Так как CGPointZero (0,0) и любое другое значение, которое вы даете точке, могут существовать в вашем контексте вы можете захотеть инициализировать NSValue своей точкой, используя:

NSValue *pointVal = [NSValue valueWithCGPoint:point];

Вы можете сделать это на основе какого-то условия, а затем позже проверить NSValue для nil. NSValue также может быть добавлен в массив, который позволит вам иметь массив точек, если вам нужно.

Чтобы получить точку позже, просто используйте:

CGPoint point = [pointVal CGPointValue]; 

Ответ 5

Создайте два свойства 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

Idk, если вы считаете, что этот способ хакерский. И я знаю, что на ваш вопрос уже был дан ответ, но у меня была одна и та же дилемма, пока я не подумал об этом.

Ответ 6

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