Простой вопрос; есть ли разница между этими значениями (и есть ли разница между BOOL и bool)? Сотрудник отметил, что они оценивают разные вещи в Objective-C, но когда я посмотрел на typedefs в своих .h файлах, YES/TRUE/true были определены как 1
и NO/FALSE/false были все определяется как 0
. Есть ли какая-то разница?
Есть ли разница между YES/NO, TRUE/FALSE и true/false в objective-c?
Ответ 1
Нет никакой практической разницы при условии, вы используете переменные BOOL
как булевы. C обрабатывает логические выражения на основе того, оцениваются ли они 0 или нет 0. Итак:
if(someVar ) { ... }
if(!someVar) { ... }
означает то же, что и
if(someVar!=0) { ... }
if(someVar==0) { ... }
поэтому вы можете оценить любой примитивный тип или выражение как логический тест (включая, например, указатели). Обратите внимание, что вы должны делать первое, а не последнее.
Обратите внимание, что есть разница, если вы назначаете тупое значение для так называемой переменной BOOL
и проверяете конкретные значения, поэтому всегда используйте их как логические и только назначая их из своих #define
значения.
Важно, никогда не тестировать булевы с использованием сравнения символов - это не только рискованно, потому что someVar
может быть присвоено ненулевое значение, которое не является YES, но, на мой взгляд, более важно, он не может правильно выразить намерение
if(someVar==YES) { ... } // don't do this!
if(someVar==NO ) { ... } // don't do this either!
Другими словами, используйте конструкции, поскольку они предназначены и задокументированы для использования, и вы избавитесь от мира обид в C.
Ответ 2
Я полагаю, что есть разница между bool
и BOOL
, проверьте эту веб-страницу для объяснения почему:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html
Поскольку BOOL
является unsigned char
а не примитивным типом, переменные типа BOOL
могут содержать значения, отличные от YES
и NO
.
Рассмотрим этот код:
BOOL b = 42;
if (b) {
printf("b is not NO!\n");
}
if (b != YES) {
printf("b is not YES!\n");
}
Выход:
б не НЕТ!
б не ДА!
Для большинства людей это ненужная проблема, но если вы действительно хотите логическое значение, лучше использовать bool
. Я должен добавить: iOS SDK обычно использует BOOL
в своих определениях интерфейса, так что это аргумент, чтобы придерживаться BOOL
.
Ответ 3
Я сделал исчерпывающий тест на это. Мои результаты должны говорить сами за себя:
//These will all print "1"
NSLog(@"%d", true == true);
NSLog(@"%d", TRUE == true);
NSLog(@"%d", YES == true);
NSLog(@"%d", true == TRUE);
NSLog(@"%d", TRUE == TRUE);
NSLog(@"%d", YES == TRUE);
NSLog(@"%d", true == YES);
NSLog(@"%d", TRUE == YES);
NSLog(@"%d", YES == YES);
NSLog(@"%d", false == false);
NSLog(@"%d", FALSE == false);
NSLog(@"%d", NO == false);
NSLog(@"%d", false == FALSE);
NSLog(@"%d", FALSE == FALSE);
NSLog(@"%d", NO == FALSE);
NSLog(@"%d", false == NO);
NSLog(@"%d", FALSE == NO);
NSLog(@"%d", NO == NO);
//These will all print "0"
NSLog(@"%d", false == true);
NSLog(@"%d", FALSE == true);
NSLog(@"%d", NO == true);
NSLog(@"%d", false == TRUE);
NSLog(@"%d", FALSE == TRUE);
NSLog(@"%d", NO == TRUE);
NSLog(@"%d", false == YES);
NSLog(@"%d", FALSE == YES);
NSLog(@"%d", NO == YES);
NSLog(@"%d", true == false);
NSLog(@"%d", TRUE == false);
NSLog(@"%d", YES == false);
NSLog(@"%d", true == FALSE);
NSLog(@"%d", TRUE == FALSE);
NSLog(@"%d", YES == FALSE);
NSLog(@"%d", true == NO);
NSLog(@"%d", TRUE == NO);
NSLog(@"%d", YES == NO);
Вывод:
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.072 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.076 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.082 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.091 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.092 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.097 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.098 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.101 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0
Ответ 4
Возможно, вы захотите прочитать ответы на question. Итак, в Objective-C (из определения в objc.h):
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#define OBJC_BOOL_DEFINED
#define YES (BOOL)1
#define NO (BOOL)0
Ответ 5
Основное (опасное!) Различие между true
и YES
заключается в сериализации JSON.
Например, у нас есть запрос к серверу JSON-типа, и нам нужно отправить true/false в смысле json:
NSDictionary *r1 = @{@"bool" : @(true)};
NSDictionary *r2 = @{@"bool" : @(YES)};
NSDictionary *r3 = @{@"bool" : @((BOOL)true)};
Затем мы конвертируем его в строку JSON перед отправкой как
NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Результат
jsonString1 // {"bool":1}
jsonString2 // {"bool":true}
jsonString3 // {"bool":true}
Из-за логики API jsonString1
может привести к ошибке.
Так что будьте осторожны с логическими значениями в Objective-C.
В итоге, только точное @YES
и приведенное значение как @((BOOL)expression)
имеют тип __NSCFBoolean
и преобразуются в true
с помощью сериализации JSON. Любые другие выражения, такие как @(expression1 && expression2)
(даже @(YES && YES)
), имеют __NSCFNumber (int)
и преобразуются в 1
в JSON.
PS Вы можете просто использовать строковое логическое значение
@{@"bool" : @"true"}; // in JSON {"bool":true}
Ответ 6
Есть тонкая ошибка, о которой никто не упомянул здесь, что я думал, что включу... больше логической ошибки, чем что-либо:
int i = 2;
if(i); //true
if(i==YES); // false
if((!!i)==YES); //true
поэтому проблема здесь в том, что (YES==1)
, а в C сравнение не является логическим, а основано на значении.
потому что YES
является просто a #define
(а не чем-то внутренним для языка), оно должно быть некоторым значением, а 1
имеет наибольший смысл.
Ответ 7
Я думаю, что они добавляют ДА/НЕТ, чтобы быть более понятными во многих случаях. Например:
[button setHidden:YES];
звучит лучше, чем
[button setHidden:TRUE];
Ответ 8
Сначала давайте рассмотрим, что такое истина и ложь и что дает им смысл в первую очередь.
мы можем построить структуру, называемую, если a затем b, иначе c в лямбда-исчислении, следующим образом:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
В JavaScript это выглядит так:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
для того, чтобы ifThenElse был полезен, нам нужна функция "true", которая выбирает правую или левую и делает это, игнорируя другую опцию, или функция "false", которая выбирает опцию "true", не принимает.
Мы можем определить эти функции следующим образом:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
в JavaScript это выглядит так:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
Теперь мы можем сделать следующее
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
с doThis и doThat is (\ a.()), потому что лямбда-исчисление не предлагает никаких услуг, таких как печать/математика/строки, все, что мы можем сделать, это ничего не делать и говорить, что мы это сделали (а затем обмануть, заменив его службами в наша система, которая обеспечивает побочные эффекты, которые мы хотим)
так что давайте посмотрим на это в действии.
(function(True) {
return (function(False) {
return (function(ifThenElse) {
return (function(doThis) {
return (function(doThat) {
return ifThenElse(True)(doThis)(doThat);
});
});
});
})
})(function(a) {
return function(b) {
return a;
}
})(function(a) {
return function(b) {
return b;
}
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
})(function(a) { console.log("you chose LEFT!"); })
(function(a) {console.log("you chose RIGHT");})();
Глубокая среда, которую можно было бы упростить, если бы нам было разрешено использовать массивы/карты/аргументы/или несколько операторов для разделения на несколько функций, но я хочу сохранить, настолько чиста, насколько я могу ограничить себя функциями с одним аргументом. только.
Заметьте, что имя True/False не имеет присущего значения, мы можем легко переименовать их в yes/no, left/right, right/left, zero/one, apple/orange. Это имеет значение в том, что какой бы выбор не был сделан, он вызван только тем, кто его сделал. Таким образом, если напечатано "LEFT", мы знаем, что выбор может быть только правдой, и на основе этого знания мы можем руководствоваться нашими дальнейшими решениями.
Итак, подведем итог
function ChooseRight(left) {
return function _ChooseRight_inner(right) {
return right;
}
}
function ChooseLeft(left) {
return function _ChooseLeft_inner(right) {
return left;
}
}
var env = {
'0': ChooseLeft,
'1': ChooseRight,
'false': ChooseRight,
'true': ChooseLeft,
'no': ChooseRight
'yes': ChooseLeft,
'snd': ChooseRight,
'fst': ChooseLeft
};
var _0 = env['0'];
var _1 = env['1'];
var _true = env['true'];
var _false = env['false'];
var yes = env['yes'];
var no = env['no'];
// encodes church zero or one to boolean
function lambda_encodeBoolean(self) {
return self(false)(true);
}
// decodes a Boolean to church zero or one
function lambda_decodeBoolean(self) {
console.log(self, self ? env['true'] : env['false']);
return self ? env['true'] : env['false'];
}
lambda_decodeBoolean('one' === 'two')(function() {
console.log('one is two');
})(function() {
console.log('one is not two');
})();
lambda_decodeBoolean('one' === 'one')(function() {
console.log('one is one');
})(function() {
console.log('one is not one');
})();
Ответ 9
Нет, YES/NO - это другой способ обратиться к TRUE/FALSE (1/0)