Цель-C: BOOL против bool

178

Я видел "новый тип" BOOL (YES, NO).

Я читал, что этот тип почти похож на char.

Для тестирования я сделал:

NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));

Хорошо видеть, что оба журнала отображают "1" (иногда в С++ bool - это int, а его размер - 4)

Так что мне просто интересно, были ли какие-то проблемы с типом bool или чем-то еще?

Можно ли просто использовать bool (который работает) без потери скорости?

Теги:
types
boolean

8 ответов

185
Лучший ответ

Из определения в objc.h:

#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
typedef bool BOOL;
#else
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

#define YES ((BOOL)1)
#define NO  ((BOOL)0)

Итак, да, вы можете предположить, что BOOL - это char. Вы можете использовать тип (C99) bool, но все фреймворки Apple Objective-C и большинство Objective-C/Cocoa кода использует BOOL, поэтому вы сэкономите головную боль, если typedef когда-либо изменится, просто используя BOOL.

  • 16
    «все рамки Apple» - неправда. Взгляните на CGGeometry.h, а именно: CG_INLINE bool __CGPointEqualToPoint (CGPoint point1, CGPoint point2) {return point1.x == point2.x && point1.y == point2.y; }
  • 57
    @ Эллиот Вы правы. Многие из фреймворков C (CoreFoundation, CoreGraphics и т. Д.) Используют C99 bool . Все платформы Objective-C используют BOOL .
Показать ещё 3 комментария
33

Как упоминалось выше, BOOL является подписанным char. bool - тип от стандарта C99 (int).

BOOL - ДА/НЕТ. bool - true/false.

См. примеры:

bool b1 = 2;
if (b1) printf("REAL b1 \n");
if (b1 != true) printf("NOT REAL b1 \n");

BOOL b2 = 2;
if (b2) printf("REAL b2 \n");
if (b2 != YES) printf("NOT REAL b2 \n");

И результат

REAL b1
REAL b2
NOT REAL b2

Обратите внимание, что bool!= BOOL. Результат ниже - ONCE AGAIN - REAL b2

b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");

Если вы хотите конвертировать bool в BOOL, вы должны использовать следующий код

BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;

Итак, в нашем случае:

BOOL b22 = b1 ? 2 : NO;
if (b22)    printf("ONCE AGAIN MORE - REAL b22 \n");
if (b22 != YES) printf("ONCE AGAIN MORE- NOT REAL b22 \n");

И так.. что мы получаем сейчас?: -)

  • 3
    Вы можете вместо троичного оператора использовать !!b1 . Конвертировать между ними
  • 1
    «НЕ РЕАЛЬНО b2» не напечатано на моем симуляторе iPhone SE.
8

На момент написания это самая последняя версия objc.h:

/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

Это означает, что на 64-битных iOS-устройствах и на WatchOS BOOL это точно такая же, как BOOL, а на всех других устройствах (OS X, 32-разрядная iOS) это signed char и даже не может быть переопределяется флагом компилятора -funsigned-char

Это также означает, что этот примерный код будет работать по-разному на разных платформах (сам тестировал):

int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
    printf("i'm 64-bit iOS");
} else {
    printf("i'm 32-bit iOS");
}

Кстати, никогда не присваивать переменные array.count BOOL, потому что около 0,4% возможных значений будут отрицательными.

8

Тип Objective-C, который вы должны использовать, - BOOL. Нет ничего похожего на собственный тип данных boolean, поэтому, чтобы убедиться, что код компиляции для всех компиляторов использует BOOL. (Он определен в Apple-Frameworks.

  • 2
    Это не совсем точно. BOOL определяется языком Objective-C (он находится в одном из objc/*.h ), а не фреймворками. Кроме того, при компиляции с C99 (который, я думаю, используется по умолчанию), существует собственный логический тип _Bool (или bool если stdbool.h ).
5

Yup, BOOL является typedef для подписанного char в соответствии с objc.h.

Однако я не знаю о bool. Это С++, да? Если он определен как подписанный char, где 1 - ДА/Истина, а 0 - NO/false, то я полагаю, что не имеет значения, какой из них вы используете.

Поскольку BOOL является частью Objective-C, однако, вероятно, имеет смысл использовать BOOL для ясности (другие разработчики Objective-C могут быть озадачены, если они видят, что используется bool).

  • 6
    _Bool определен в C99, и в стандартном заголовке stdbool.h определен макрос bool (который расширяется до _Bool), и здесь также определены true / false.
4

Другим различием между bool и BOOL является то, что они не преобразуются точно в те же объекты, когда вы выполняете наблюдение за ключевыми значениями, или когда вы используете такие методы, как [NSObject valueForKey:].

Как сказано выше, BOOL - char. Таким образом, он преобразуется в NSNumber с char. Этот объект неотличим от NSNumber, созданного из обычного char, такого как "A" или "\ 0". Вы полностью потеряли информацию о том, что изначально у вас был BOOL.

Однако, bool преобразуется в CFBoolean, который ведет себя так же, как NSNumber, но который сохраняет логическое происхождение объекта.

Я не думаю, что это аргумент в дискуссии BOOL против bool, но это может вас укусить однажды.

В общем, вы должны пойти с BOOL, так как это тип, используемый везде в API Cocoa/iOS (разработанный до C99 и его собственный тип bool).

2

Принятый ответ был отредактирован, и его объяснение немного неверно. Код образца обновлен, но текст ниже остается прежним. Вы не можете предположить, что BOOL - это char, поскольку он зависит от архитектуры и платформы. Таким образом, если вы запускаете код на 32-битной платформе (например, iPhone 5) и print @encode (BOOL), вы увидите "c". Он соответствует char type. Но если вы запустите свой код на iPhone 5s (64 бит), вы увидите "B". Это соответствует тип bool.

1

Я иду против конвенции здесь. Мне не нравится typedef для базовых типов. Я думаю, что это бесполезная направленность, которая удаляет ценность.

  • Когда я увижу базовый тип в вашем источнике, я сразу пойму это. Если это typedef, я должен посмотреть его, чтобы увидеть, что я действительно имею в виду.
  • При переносе в другой компилятор или добавлении другой библиотеки их набор typedef может конфликтовать и вызывать проблемы, которые трудно отлаживать. На самом деле я просто сделал это. В одной библиотеке логическое значение было typedef'ed для int, а в mingw/gcc оно было напечатано на char.
  • 4
    Ну ... можно ожидать, что вы знаете стандартные определения типов вашего языка (например, size_t ), и оба типа bool (C99) и BOOL (ObjC) попадают в эту категорию. И если ваш код потерпел неудачу из-за изменения typedef, виноват ваш код, поскольку вы, очевидно, не рассматривали typedef как непрозрачную вещь, а полагались на его реализацию на одной платформе. (Ничего не стыдно, бывает, но это не виноват тип.)
  • 1
    «Стандартные» определения типов не кажутся очень стандартными (например, какое-то время MS не поддерживала стандарты posix и т. Д.). Если вы не используете typedefs, тогда проблема с изменением typedefs или его отличиями на разных компиляторах устраняется.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню