В Objective-C, безопасный и хороший способ сравнить 2 значения BOOL?

Я хочу сравнить 2 значения BOOL в target-c.

Я обнаружил, что (3) - (6) из следующего кода работает.
(1) - (2) не работает, потому что BOOL простоsigned char.

(3) работает и очень читабелен, но я думаю,bool не является целью-c.
С помощьюbool в коде цель-с это хорошо?

Какой безопасный и хороший способ сравнить 2 значения BOOL в target-c?
Есть ли другие лучшие способы сравнения?

BOOL b = YES;
BOOL c = 2;

NSLog(@"(1) %d", b == c); // not work
NSLog(@"(2) %d", (BOOL)b == (BOOL)c); // not work
NSLog(@"(3) %d", (bool)b == (bool)c);
NSLog(@"(4) %d", !b == !c);
NSLog(@"(5) %d", !!b == !!c);
NSLog(@"(6) %d", (b != 0) == (c != 0));

Результаты:

(1) 0
(2) 0
(3) 1
(4) 1
(5) 1
(6) 1
 trojanfoe21 июн. 2012 г., 10:35
2 не является действительнымBOOL значение; толькоYES а такжеNO являются. То, что вы делаете, неверно.
 Oleg Trakhman21 июн. 2012 г., 10:43
Я согласен с trojanfoe, а также думаю, что XCode должен генерировать предупреждение в случае таких назначений. Неправильные назначения BOOL являются источником ужасных ошибок.
 nhahtdh21 июн. 2012 г., 10:37
@trojanfoe: Дело в том, что Obj-C с радостью примет присвоение номера BOOL, и вы даже можете выполнять побитовую работу с ним.
 trojanfoe21 июн. 2012 г., 11:19
@NikolaiRuhe Конечно, однако, задавая вопрос о безопасном использованииBOOL а затем присваивая2не действителен.
 nhahtdh21 июн. 2012 г., 10:37
4-й метод выглядит хорошо для меня. Он короткий и безопасно конвертирует значение в 0 или 1.

Ответы на вопрос(6)

objc.h:

typedef signed char     BOOL; 
....

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

Судя по всему, BOOLsigned char, так что это правда, что вы можете назначить номер переменнойBOOL тип, который испортит сравнение (так как сравнение - целочисленное сравнение).

Я думаю, что ваш метод (4), использующий отрицание для преобразования произвольного интегрального значения в 0 или 1, является хорошим коротким способом безопасного сравнения логического значения 2 BOOL.

BOOLотвечая на вопрос, что вы подразумеваете под "2"

в вашем контексте 2 = ДА

Int number = 2;
BOOL c = (number == 2); //2 is YES

это & gt; 0 = ДА

Int number = 2;
BOOL c = (number > 0); //2 is YES

Это зависит только от того, что ИСТИННО, а что Неверно в вашем приложении

 js_21 июн. 2012 г., 11:19
Благодарю. Я всегда пытаюсь преобразовать в действительный BOOL при назначении после того, как узнал, что кратные 256 неявно преобразуются в 0 (НЕТ). Но возможно, что метод, созданный другим человеком, возвращает значение BOOL, отличное от 0/1. И я не конвертирую возвращенное значение BOOL в действительное значение типа BOOLb = !![obj methodWhchReturnsBOOL]; Так,c = 2 может случиться.
 21 июн. 2012 г., 12:12
Этот вид преобразования не требуется, если вы используете BOOL правильно. Если вам нужно подумать об этом, то вы делаете что-то в корне неправильно. Выражение (B & amp; C) вернет YES, даже если c равно 2, а b равно 1. Можно основывать весь ваш код на выражениях такого типа, и это правильный путь в булевой алгебре. (именно поэтому он называется BOOL / bool / Boolean). См. мой ответ для ссылок.

я хотел бы отметить, что сравнение булев на равенствоnot очень распространенная операция.BOOL не является типом, это просто макрос, который скрывает тот факт, что логические значения являются только целыми числами. Для каждой логической операции вы должны использовать программные структуры и операторы, которые могут правильно обрабатывать целые числа как логические:

например: if (condition1 == NO) {} должно бытьif (!condition1) {}

if (condition1 == condition2) {}
 может быть
if ((condition1 && condition2) || (!condition1 && !condition2)) {}
или лучше
BOOL newCondition = (condition1 && condition2) || (!condition1 && !condition2); if (newCondition) {}

Кратчайший способ написания условия не должен быть наилучшим.

 21 июн. 2012 г., 17:24
Также ради правильности:BOOL это не макрос, а определение типа.
 21 июн. 2012 г., 17:22
Я не думаю, что сравнение булевых значений редко. Одним из распространенных случаев является установщик свойства BOOL с ярлыком быстрого возврата: - (void) setAnimate: (BOOL) animate {if (_animate == animate) return; // еще сделать все, что нужно для настройки или снятия анимации}
 26 авг. 2012 г., 19:28
 21 июн. 2012 г., 18:03
Спасибоtypedef нота.old value check это что-то действительно особенное. Обычно вы вообще не заботитесь о типе собственности и даже не должны знать, что это BOOL.

ваш код будет поврежден. Что бы вы ни получили после этого, это то, что вы заслуживаете.

Поэтому единственный разумный способ сравнить две BOOL a и b

if (a == b) ...
if (a != b) ...
 24 мар. 2014 г., 18:38
Я бы сказал, что единственный разумный путьif(a && b) а такжеif (!a && b), поскольку это операторы в мертвых будут настоящие логические операции, в то время как== а также!= являются числовыми операторами.
Решение Вопроса

bool в Objective-C как части стандарта C99 (& # xA7; 7.16). По моему мнению, это также лучший способ обеспечить безопасное сравнение булевых типов.

Единственная причина не использоватьbool везде этоBOOL вездесущ в Objective-C и структурах.

 js_21 июн. 2012 г., 14:32
Благодарю. я думал, что Bool был C ++. @ JeremyP, почемуfoo = bar; bar = foo; не безопасны?
 js_22 июн. 2012 г., 07:51
@JeremyP, так почему ты это делаешь?foo = bar ? true : false; или жеbar = foo ? YES : NO;? Компилятор XCode содержит ошибки?
 21 июн. 2012 г., 12:31
я используюbool везде, кроме тех случаев, когда API-интерфейс Cocoa требуетBOOL, Безопасное преобразование из одного в другое было бы (foo - это bool, а bar - это BOOL):foo = bar ? true : false; или жеbar = foo ? YES : NO;
 21 июн. 2012 г., 15:45
Назначениеtrue или жеfalse кBOOL является действительным и безопасным. Стандарт говорит, что они расширяются до целочисленных констант0 или же1 (также в & # xA7; 7.16).
 21 июн. 2012 г., 22:43
@js_ Это всегда работает. Прямое назначение также должно быть безопасным с современными компиляторами без ошибок.

рации XOR.

Попытка сравнить два логических значения напрямую - это неправильное использование основ булевой алгебры: http://en.wikipedia.org/wiki/Boolean_algebra_(logic)

Когда вы делаете

BOOL a = (b == c);

тогда это значение может вернуть false, даже если b и c верны. Однако выражение b & amp; c всегда будет возвращать YES, если b и c истинны, то есть больше 0, и NO в противном случае.

Вместо этого это то, что вы на самом деле пытаетесь сделать:

BOOL xor = b && !c || !b && c;
BOOL equal = !xor;

эквивалентно

BOOL equal = !(b && !c || !b && c);

или же

BOOL equal = (b && c) || (!b && !c)

Если вам нужно потратить время, чтобы убедиться, что ваши значения BOOL нормализованы (т.е. установлены в 1 или 0), то вы делаете что-то не так.

 25 июн. 2012 г., 11:12
С программной точки зрения это безопасно и может считаться «чистым» некоторые, но я придерживаюсь мнения, что логическое выражение должно быть автономным выражением, которое будет разбито на использование & amp; & amp; только и имеет возвращаемое значение true или false. Сравнение двух булевых выражений друг с другом, нормализованных или нет, не является регулярной булевой алгеброй. ДА: if (true) if (false) if (bool1 & amp; bool2) if (bool1 & amp;! Bool2 || int1 == int2) if (int1 == int2) и т. Д. NO: if (bool1 == bool2) if (bool1 == true) if (! Bool1 == bool2) и так далее. Все они программно правильны, но последние не очень хороши для меня.
 21 июн. 2012 г., 13:40
удобочитаемость может быть улучшена из имен переменных. Если вы, например, хотите проверить, голоден ли человек, но не устал или не устал, но не голоден, и у вас есть два одинаковых именива, тогда выражение (голодный и усталый) || (! голодный и усталый) имеет больше смысла, чем выражение (голодный! = усталый). (Как голодный может быть равен усталому, и что бы это значило?)
 22 июн. 2012 г., 02:57
Четвертое выражение в вопросе OP фактически решает проблему быстро и чисто. Он просто нормализует число до 0 или 1, затем== будет вести себя как XNOR (НЕ XOR). Другие выражения (3 и 5, 6) также верны.
 js_21 июн. 2012 г., 13:22
спасибо Джейк! я думаю, что вы и @Sulthan правы. это красиво, но это дольше и менее читабельно / доступно для записи, чем !! или (бул). почему у c нет логического оператора xor?

Ваш ответ на вопрос