Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Cocoa——切换布尔而不重复其名称_Objective C_Cocoa_Boolean - Fatal编程技术网

Objective c Cocoa——切换布尔而不重复其名称

Objective c Cocoa——切换布尔而不重复其名称,objective-c,cocoa,boolean,Objective C,Cocoa,Boolean,如果一个BOOL有一个很好的短名称,那么很容易写出: myBOOL = !myBOOL; 但是如果那家伙的名字很长呢 objectWithLongishName.memberWithLongishName.submember.myBOOL = !(objectWithLongishName.memberWithLongishName.submember.myBOOL); 。看起来不那么漂亮 我想知道是否有一种简单的方法可以在不输入两次名称的情况下切换BOOL?否在(Objective-)

如果一个BOOL有一个很好的短名称,那么很容易写出:

myBOOL = !myBOOL;
但是如果那家伙的名字很长呢

objectWithLongishName.memberWithLongishName.submember.myBOOL = !(objectWithLongishName.memberWithLongishName.submember.myBOOL);  
。看起来不那么漂亮


我想知道是否有一种简单的方法可以在不输入两次名称的情况下切换BOOL?

否在(Objective-)C中没有一种明显的方法可以实现您所描述的(不使用预处理器宏),但请参阅Seva的答案,以获得一种可能的(尽管可能很脆弱)解决方案。更重要的是,类似于
objectWithLongishName.memberWithLongishName.submember.myBOOL
的内容表示违规;您应该直接向需要访问
submember.myBOOL

的任何代码单元提供
submember
submember
类的方法,以便为您切换它

- (void) toggleMyBOOL {
  self.myBool = !self.myBool;
}
然后你可以做:

[objectWithLongishName.memberWithLongishName.submember toggleMyBOOL];
或者,如果是目标C++:

inline void NOT(BOOL &b)
{
    b = !b;
}
还有一个:

MyBooleanYaddaYadda ^= YES;
这有点脆弱——它将破坏遗留C代码,这意味着任何非零整数的计算结果都为true。但是苹果的框架代码也是如此——我在Cocoa中遇到过这样的情况,当一个非零、非一的int作为BOOL传递时,不会产生与传递YES相同的效果

但是,它不依赖于YES的位模式,只依赖于NO为0。考虑到C将整数解释为逻辑值的方式,这几乎是给定的。此外,它不假定BOOL的实际数据类型(顺便说一句,Cocoa上的BOOL是
有符号的char


Cocoa上YES的位模式为1。但这不是一个普遍的惯例。在一些没有内置布尔数据类型的平台上,用作逻辑TRUE的整数常量是
-1
-所有一位。如果解释为无符号,则为0xFFFFFFFF。这种编码有一个模糊的优点,即bitwize NOT(C中的~operator)等价于逻辑NOT(C中的!operator)。也就是说,~0xFFFFFFFF是0,i。e~真是假。如果将TRUE定义为1,则不会以这种方式工作。

使用XOR。在C中,这是^

BOOL x = YES;
x ^= YES; // it's now NO
x ^= YES; // it's now YES
x ^= YES; // it's now NO
x ^= YES; // it's now YES
x ^= YES; // it's now NO
x ^= YES; // it's now YES
...

编辑:显然已经有人发布了。我想我应该说我从来没有在代码中实际使用过它。:-)

您有一组可爱的答案,重点是将“是”转换为“否”,或将“否”转换为“是”,但没有任何答案涉及到代码中的架构问题

嗯,有一些答案。我瞎了

也就是说,你有:

objectWithLongishName.memberWithLongishName.submember.myBOOL =
    !(objectWithLongishName.memberWithLongishName.submember.myBOOL);  
这闻起来像是潜在的封装违规。特别是(假设这是一个模型层),这意味着对象子图的连通性被公开暴露——有效地展平到——路径的入口点;无论
objectWithLongishName
是什么,现在都必须对路径其余部分的对象内部有相当深入的了解

通常,您不会沿着关键路径深入模型层以编辑Cocoa绑定层之外的状态(即使这样也有点脆弱)


有时候,这样漫长的道路是有道理的。在这种情况下,我会留下你上面的über详细表格作为一个视觉指示,表明封装被故意撕碎。

只是好奇,你能用Objective-C中的数字乘以
bool
吗?你能用LongishName.memberWithLongishName.submember.myBOOL*=-1做一些事情吗?这似乎是一个非常非常糟糕的方法,但我现在只是想知道它是否有效…@frust:撇开其他问题不谈,从算术上讲,它是如何工作的<代码>0*-1=0
@Georg Fritzsche:哈哈哈!好的,说得好。我想我在哪里见过这个把戏,但我不记得在哪里(虽然我知道它不是Objective-C)。你可以想象你可以做
myBool^=1
…但我不会。@William:你真的应该指定一个平台。BOOL数据类型和YES/NO常量不是Objective C本身的一部分,它们在Cocoa头中定义。目标C和C一样,没有布尔数据类型。为什么aBool^=YES不可行?@Kalle,说得对。我认为@Seva Alekseyev非常清楚地说明了这一点。使用
^=
可能很脆弱,但在许多情况下都会起作用。请注意,这是一种按位异或,这意味着如果出于某种原因将
x
设置为除1或0以外的任何值,它将始终保持为真,因为您只翻转最低位。使用
~NO
将用另一个问题来代替这个问题:您将翻转所有位,结果是相同的:
x
只是在两个真值之间交替。这就是为什么我将其作为注释发布,并说“…但我不会”;)但它确实是“整洁”的。如果您设法使布尔值等于1或0以外的值,那么是的,您将遇到问题。但不管怎样,你不会吗?从代码清晰的角度来看,它有点失败。随便一看,这看起来像是一个“是”的任务。如果经常使用它,这个习惯用法可能会脱颖而出,但如果换个角度看,可能会让人有点挠头。在我看来,简洁和缺乏必要的相关基础设施(即宏定义)超过了这个缺点。这就是我接受这个答案的原因。然而,每个人都有自己的答案。@Barry Wark提到了这一点(违反了Demeter法)。事实上,第一个(或第一个)答案(Barry Wark的答案)提到了这一点。
objectWithLongishName.memberWithLongishName.submember.myBOOL =
    !(objectWithLongishName.memberWithLongishName.submember.myBOOL);