Значение по умолчанию для структуры Objective-C и как тестировать

Я пытаюсь проверить, установлено ли свойство. Я знаю, что с объектами, которые у меня есть:

CGRect ppGoalFrame;
LocalPlaySetup *localPlaySetup;

и я могу проверить

if (localPlaySetup == nil)

но если я попытаюсь проверить CGRect с помощью == nil или == NULL

if (ppGoalFrame == nil)

я получил

invalid operands to binary == (have 'CGRect' and 'void *')

Так это CGRect "недействительно", "ноль", "ноль" ...? до того, как он установлен? Очевидно, я не могу сравнивать CGrect с указателем void (я не могу использовать ppGoalFrame == void); есть ли другой способ проверить это? Objective-C пока довольно легко понять, но как только C вырисовывается, я немного теряюсь.


person typeoneerror    schedule 10.03.2010    source источник


Ответы (7)


Только указатели могут быть нулевыми. CGRect - это структура, она представляет собой непрерывный блок памяти. Единственный способ узнать, настроен ли он, это проверить его содержимое.

Apple предоставляет константу CGRectNull. Вы можете установить для своей переменной это значение и использовать функцию CGRectIsNull, чтобы определить, установлена ​​ли она. CGRectNull - это не то же самое, что CGRectZero, поэтому вам не нужно беспокоиться, если желаемое значение равно нулю.

Обратите внимание, что CGRectNull просто содержит структуру CGRect, заполненную значениями, которые Apple может позже идентифицировать для функции CGRectIsNull. Это не то же самое, что при сравнении указателей.

person Andrew    schedule 10.03.2010
comment
Закончился использованием CGRectIsEmpty для тестирования. Необязательно устанавливать их каким-либо образом. Ваш ответ привел меня к правильному пути, так что спасибо. - person typeoneerror; 10.03.2010

Все переменные экземпляра в классе Objective-C инициализируются нулем. Таким образом, все указатели равны nil, числа равны 0, а структуры обнулены. Поскольку CGRect представляет собой простую структуру, она будет инициализирована значением origin.x=0, origin.y=0, size.width=0, size.height=0.

Итак, чтобы проверить, установлен ли ваш CGRect, вам нужно сравнить его (по значению) с нулем. Функция CGRectIsEmpty сделает именно это:

if (CGRectIsEmpty(ppGoalFrame))
{
    // ...
}
person gavinb    schedule 10.03.2010
comment
+1 отличный ответ. Вы можете отредактировать его, чтобы использовать CGRectIsEmpty IMO. - person Dan Rosenstark; 01.08.2012
comment
Спасибо @gavinb, отлично. Лично я бы удалил ссылку CGRectEqualToRect, поскольку теперь это устаревший код. - person Dan Rosenstark; 01.08.2012

От 1_:

/* Return true if `rect' is empty (that is, if it has zero width or height),
   false otherwise. A null rect is defined to be empty. */

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

CGRect newRect = CGRectNull;
person Martin Bissegger    schedule 07.11.2011

Универсальной ценности «ничего» не существует. Там nil для объектов и NULL для указателей, но нет эквивалента для простых типов значений - они всегда имеют некоторое значение, даже если это просто чушь. Вы можете взять произвольное значение и сказать: «Я буду называть это нулевым значением для этого типа» (скажем, #define IntNull 4444444 и надеюсь, что какое-то вычисление случайно не вернет это значение), но настоящего нулевого значения нет.

В частности, в случае CGRect Apple использовала тактику «выбрать произвольное значение» и определила CGRectNull, но переменные CGRect не установлены для этого по умолчанию - вы должны специально установить это самостоятельно. По умолчанию для переменных экземпляра CGRect установлено значение CGRectZero, но помните, что это обычная структура CGRect в местоположении (0,0) с 0 шириной и 0 высотой. А локальные CGRects в функции имеют совершенно непредсказуемое значение.

person Chuck    schedule 10.03.2010

Вы также можете обернуть CGRect в NSValue:

[NSValue valueWithCGRect:CGRectMake(x, y, width, height)]

А затем избегайте значения nil.

person Carlos Ricardo    schedule 01.04.2013

На самом деле есть очевидное и элегантное решение (смеется):

SomeStruct someStruct = {0};

Которая просто заполняет все «элементы» структуры нулями.

person Nikita    schedule 28.04.2019

Я не думаю, что вы можете провести двоичное сравнение структуры C, которая является что такое CGRect. Быстрый поиск в Google и проверка справочника C для чайников ничего не дали. Вы можете объявить CGRect ppGoalFrame, инициализировать элементы структуры значениями по умолчанию (если они еще не были) и протестировать элементы структуры.

Обновление редактирования: этот вопрос был задан для C конструкции.

person C.D. Reimer    schedule 10.03.2010
comment
При обсуждении переменных экземпляра в Objective-C все обстоит иначе. - person gavinb; 10.03.2010
comment
@gavinb: Может быть. Я все еще освежаю свой C, прежде чем погрузиться в Objective-C. - person C.D. Reimer; 10.03.2010