Значение по умолчанию структуры Objective-C и способ тестирования
Я пытаюсь проверить, установлено ли свойство. Я знаю, что с объектами, которые у меня есть:
CGRect ppGoalFrame;
LocalPlaySetup *localPlaySetup;
и я могу проверить
if (localPlaySetup == nil)
но если я попытаюсь проверить CGRect на == nil или == NULL
if (ppGoalFrame == nil)
Я получаю
invalid operands to binary == (have 'CGRect' and 'void *')
Итак, CGRect
"void", null, nil...? прежде чем он установит? Очевидно, я не могу сравнивать CGrect с указателем void (я не могу использовать ppGoalFrame == void
); есть ли другой способ проверить это? Objective-C до сих пор довольно легко понять, но как только появляется C, я немного теряюсь.
Ответы
Ответ 1
Только указатели могут быть пустыми. CGRect - это структура - он представляет собой непрерывный блок памяти. Единственный способ узнать, был ли он установлен для проверки содержимого.
Apple предоставляет константу CGRectNull
. Вы можете установить эту переменную и использовать функцию CGRectIsNull, чтобы определить, была ли она установлена. CGRectNull
не совпадает с CGRectZero
, поэтому вам не нужно беспокоиться о том, что нулевое значение равно нулю.
Обратите внимание, что CGRectNull просто содержит структуру CGRect, заполненную значениями, которые Apple может позже идентифицировать для функции CGRectIsNull. Это не то же самое, что и при сравнении указателей.
Ответ 2
Все переменные экземпляра в классе Objective-C инициализируются до нуля. Таким образом, все указатели nil
, числа - 0, а структуры - обнулены. Поскольку CGRect является простой структурой, он будет инициализирован origin.x=0, origin.y=0, size.width=0, size.height=0
.
Итак, чтобы проверить, установлен ли ваш CGRect
, вам нужно сравнить его (по значению) с нолем. Функция CGRectIsEmpty
будет выполнять именно это:
if (CGRectIsEmpty(ppGoalFrame))
{
// ...
}
Ответ 3
От CGGeometry.h
:
/* 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;
Ответ 4
Нет универсального значения "ничего". Там nil
для объектов и NULL
для указателей, но нет эквивалента для простых типов значений - они всегда имеют некоторое значение, даже если это просто вздор. Вы можете принять произвольное значение и сказать: "Я собираюсь назвать это нулевым значением для этого типа" (скажем, #define IntNull 4444444
и надеюсь, что некоторые вычисления никогда не возвратят это значение случайно), но нет реального значения null.
В случае с CGRect, в частности, Apple использовала тактику "выбрать произвольное значение" и определяла CGRectNull
, но переменные CGRect по умолчанию не установлены - вам нужно специально установить ее самостоятельно. По умолчанию переменные экземпляра CGRect установлены на CGRectZero
, но помните, что это просто нормальная структура CGRect в местоположении (0,0) с 0 шириной и 0 высотой. И локальные функции CGR в функции имеют совершенно непредсказуемое значение.
Ответ 5
Вы также можете обернуть CGRect в NSValue:
[NSValue valueWithCGRect:CGRectMake(x, y, width, height)]
И затем избегайте значения nil
.
Ответ 6
Я не думаю, что вы можете выполнить двоичное сравнение структуры C, которая что такое CGRect. Быстрый поиск Google и проверка справочника C-Dummies Desk ничего не изменили. Вы можете объявить CGRect ppGoalFrame, инициализировать члены структуры со значениями по умолчанию (если они еще не установлены) и проверить элементы структуры.
Update Edit: этот вопрос был задан для структур C.
Ответ 7
На самом деле есть очевидное и элегантное решение (смеется):
SomeStruct someStruct = {0};
Который просто заполняет все "элементы" структуры нулями.