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

Значение по умолчанию структуры 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, я немного теряюсь.

4b9b3361

Ответ 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};

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