Как проверить, был ли 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;
}
Ответы
Ответ 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