Причины не использовать _Bool в Objective-C?
Так как C99, C теперь имеет собственный булев тип, _Bool
. Objective-C, как строгий надмножество C, наследует это, но когда он был создан еще в 1980-х годах, не было C-типа Boolean, поэтому Objective-C определено BOOL
как signed char
.
Все Cocoa использует BOOL
, как и весь код не-NeXT/Apple Cocoa, который я видел. Очевидно, что для совместимости с существующими протоколами (например, -applicationShouldTerminateAfterLastWindowClosed:
от NSApplicationDelegate
) предпочтительным является сопоставление уже заявленного типа, если только для предотвращения предупреждения.
Для целей чистоты/удобочитаемости stdbool.h
определяет BOOL
как синоним _Bool
, поэтому те из нас, кто не хочет лишних подчеркиваний в нашем коде, могут использовать это.
Три других полезных примечания:
-
@encode(_Bool)
оценивается как "B"
. (@encode(BOOL)
оценивается до "c"
, для signed char
.)
-
sizeof(_Bool)
оценивается как 1
, что следует из определения C99, что _Bool
является настолько большим, насколько необходимо для хранения двух возможных значений. ( Изменить: На самом деле, стандарт говорит только о том, что он должен быть "достаточно большим", чтобы удерживать эти два значения, он не устанавливает верхнюю границу и, по сути, Mac OS X на 32-битной PowerPC определяет ее как 4 байта. Разница в размерах - это еще одна вещь, которая может быть связана с возможными проблемами совместимости BOOL
-vs.- BOOL
.)
- В этом примечании единственными двумя возможными значениями a
_Bool
являются 1 и 0. Любые другие значения преобразуются в одно из них при назначении, как если бы вы делали двойное отрицание (!!
) или тестировали неравенство против 0 (!= 0
). Единственные способы получить _Bool
с некоторым другим значением - это обычные магии: наложение псевдонимов и союзы.
Есть ли причина не использовать _Bool
/BOOL
в новом коде?
Ответы
Ответ 1
Я думаю, что вы все, но ответили на свой собственный вопрос: причина не использовать _Bool в новом коде Cocoa заключается в том, что до тех пор, пока Apple не изменит свои фреймворки на использование _Bool (или, скорее, bool, определенный в stdbool.h), вы нарушаете соглашение и, возможно, совместимость (по крайней мере, без хаков) с помощью _Bool или bool. Хотя я только замалчивался в программировании Cocoa уже пару лет, я бы поспорил, что если Apple включит _Bool вообще, они, вероятно, просто переопределяют макрос BOOL, чтобы использовать новый тип за кулисами в любом случае, чтобы избежать неисчерпаемое редактирование их рамок и документации.
Сказав это (и позвольте мне предисловие к этому, отказавшись от того, что мне еще не нужно смешивать код C с Objective-C и не знаю соглашений для этого), у вас есть гораздо лучший пример для использования новый _Bool внутри функций C, возможно, с предостережением, что он используется только внутри и не просит метод Objective-C пройти в _Bool, чтобы избежать путаницы для будущих программистов. Разумеется, вам также должно быть удобно, что всегда требуется компиляция C99, и у людей все еще может быть причина, которой следует избегать. Учитывая, что YES - это макрос для 1, а NO - макрос для 0, кажется, нет большого выигрыша в необходимости использования более новой версии C для получения другого значения char, которое использует только 1 или 0.
Честно говоря, когда дело доходит до этого, вы можете обойти любую из этих причин с достаточным количеством хакеров или ограничений на повторное использование, но оправданием конца является то, что он (в настоящее время) не является частью Cocoa/Objective-C сленг, и его преимущества, вероятно, не перевесят потери в удобочитаемости и/или добавили путаницу других программистов-программистов, не имеющих доступа к информации, читающих ваш код.
Ответ 2
С Objective-C просто используйте тип данных BOOL...
Для C я рекомендую следующие макросы, которые также будут работать с ANSI-C (C-89):
#ifndef __bool_true_false_are_defined
#ifdef _Bool
#define bool _Bool
#else
#define bool char
#endif
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif
Ответ 3
Я согласен с @pst. Objective-C не скрывает C, но он все еще является слоем поверх C. Это означает, что Objective-C - это просто другой слой.
Я думаю, что это проблема языкового контекста. Это не всегда понятно, но мы знаем, что такое контекст C и контекст Objective-C. Как American
vs Americano
. Они, по сути, имеют то же значение, но различают контекст и могут немного отличаться от контекстов. И это может сделать некоторую очевидную информацию для читателя, когда эти маленькие детали накапливаются. Это поможет повысить читаемость кода.
И я считаю, что вы должны знать важность читаемости. Если читаемость не важна, нам не нужно использовать какие-либо вкладки или пробелы.:)
В качестве других примеров существуют nil
vs NULL
, strlen()
vs -[NSString length]
. BOOL
может сказать: "Я Objective-C код". сильно, который _Bool
не может.