如何在 ios 中将开关状态转换为整数
How to convert switch state into integer in ios
我使用五个开关来处理不同类型的通知。为了记住开关的状态,我正在考虑将五个开关的状态转换为一个整数。例如,如果我的开关状态如下,01010 那么整数应该是 10。请帮助我如何实现这一点。
- 首先提取每个开关值并将其存储在一个字符串中
- 现在将字符串转换为十进制/整数值,如下所示:-
NSString * binarystring = @"01010";
long decimalValue = strtol([binarystring UTF8String], NULL, 2);
NSLog(@"%ld", decimalValue );
编辑
获取单个字符串中的所有开关控制值:-
NSString *binarystring = [[NSString alloc] initWithFormat:@"%i%i%i%i%i",self.switch1.isOn,self.switch2.isOn,self.switch3.isOn,self.switch4.isOn,self.switch5.isOn];
(为什么要把你的 5 个开关值编码成一个整数?存储 5 个布尔值并不难。也就是说,问题是如何去做...)
重要的一点:BOOL 值不是 0 和 1
Objective-C 是 C 的超集,在原始 C 中没有布尔类型 - 相反它只是使用整数类型,解释为 0 为假,其他任何东西 是真的。
Objective-C 将 BOOL
定义为 signed char
,这是一个 8 位有符号整数类型(因为字符在 C 中只是一种整数类型)。所以在Objective-C中0为假,-128..-1、1..127都为真。 NO
定义为 0
,YES
定义为 1
,但各种操作可能会产生其他值。
要从 BOOL
b
得到 0
或 1
,您可以使用条件运算符:
b ? 1 : 0
然而,内置逻辑运算符 根据定义 将始终 return 0
或 1
而绝不会是任何其他可能的值。 !
运算符是逻辑非,两个非让你回到你开始的地方所以:
!!b
也会给你一个0
或1
。
在任何采用 BOOL
并尝试将其用作 0
或 1
的代码中,您实际上应该使用上述之一(或等效项)。
一种解决方法:使用字符串
您的问题已被解释为在编码过程中使用字符串作为中介。首先假设 class 将您的五个按钮作为简单数组存储在一个实例变量中(它将允许我们循环):
const int kSWITCH_COUNT = 5; // let's not hard code it everywhere
@implemention MyClass
{
Switch *switches[kSWITCH_COUNT];
}
然后字符串方法是这样的:
- (void) stringMethod
{
NSMutableString *binarystring = NSMutableString.new;
// build up the string one value at a time, note the !! so we only get 0 or 1 values
for (int ix = 0; ix < kSWITCH_COUNT; ix++)
[binarystring appendFormat:@"%d", !!switches[ix].isOn];
long decimalValue = strtol([binarystring UTF8String], NULL, 2);
NSLog(@"Encoded: 0x%lx", decimalValue);
}
此方法有效,但它是一种相当迂回的获取结果的方法 - 你有 5 个整数(布尔)值,你想将它们组合成一个整数,为什么涉及字符串?
更好的解决方法:使用整数
(Objective-)C 提供按位运算符来执行移位、或、与等操作,这些操作将整数类型视为有序的位集合——这就是它们在计算机上的含义。
<<
运算符左移,例如0x1 << 1
产生 0x2
,即 << 1
相当于乘以 2。|
运算符是按位或,例如0x1 << 1 | 1produces
0x3`。您的问题的答案现在很容易得出:
- (void) shiftMethod
{
unsigned int encoded = 0;
for (int ix = 0; ix < kSWITCH_COUNT; ix++)
encoded = (encoded << 1) | !!switches[ix].isOn;
NSLog(@"Encoded: 0x%x", encoded);
}
如果你不喜欢 shifts 和 ors 你可以使用乘法和加法:
encoded = encoded * 2 + !!switches[ix].isOn;
上面直接解决了问题,没有转换to/from中间字符串。它恰好也快得多,但是在应用程序的总体方案中,这两种方法都可能不会占用很大一部分执行时间,因此您不应该 select 基于此。
第三条路
如果您希望 set/get 整数的各个位,您可以使用具有位域宽度的 struct
类型。这些可以让您直接 set/get 整数的位 - 不需要移位等 - 您可能会发现它们很有用,但它们更像是 "low level"。任何一本关于 C 的好书都会告诉你如何使用这些。
HTH
我使用五个开关来处理不同类型的通知。为了记住开关的状态,我正在考虑将五个开关的状态转换为一个整数。例如,如果我的开关状态如下,01010 那么整数应该是 10。请帮助我如何实现这一点。
- 首先提取每个开关值并将其存储在一个字符串中
- 现在将字符串转换为十进制/整数值,如下所示:-
NSString * binarystring = @"01010";
long decimalValue = strtol([binarystring UTF8String], NULL, 2);
NSLog(@"%ld", decimalValue );
编辑
获取单个字符串中的所有开关控制值:-
NSString *binarystring = [[NSString alloc] initWithFormat:@"%i%i%i%i%i",self.switch1.isOn,self.switch2.isOn,self.switch3.isOn,self.switch4.isOn,self.switch5.isOn];
(为什么要把你的 5 个开关值编码成一个整数?存储 5 个布尔值并不难。也就是说,问题是如何去做...)
重要的一点:BOOL 值不是 0 和 1
Objective-C 是 C 的超集,在原始 C 中没有布尔类型 - 相反它只是使用整数类型,解释为 0 为假,其他任何东西 是真的。
Objective-C 将 BOOL
定义为 signed char
,这是一个 8 位有符号整数类型(因为字符在 C 中只是一种整数类型)。所以在Objective-C中0为假,-128..-1、1..127都为真。 NO
定义为 0
,YES
定义为 1
,但各种操作可能会产生其他值。
要从 BOOL
b
得到 0
或 1
,您可以使用条件运算符:
b ? 1 : 0
然而,内置逻辑运算符 根据定义 将始终 return 0
或 1
而绝不会是任何其他可能的值。 !
运算符是逻辑非,两个非让你回到你开始的地方所以:
!!b
也会给你一个0
或1
。
在任何采用 BOOL
并尝试将其用作 0
或 1
的代码中,您实际上应该使用上述之一(或等效项)。
一种解决方法:使用字符串
您的问题已被解释为在编码过程中使用字符串作为中介。首先假设 class 将您的五个按钮作为简单数组存储在一个实例变量中(它将允许我们循环):
const int kSWITCH_COUNT = 5; // let's not hard code it everywhere
@implemention MyClass
{
Switch *switches[kSWITCH_COUNT];
}
然后字符串方法是这样的:
- (void) stringMethod
{
NSMutableString *binarystring = NSMutableString.new;
// build up the string one value at a time, note the !! so we only get 0 or 1 values
for (int ix = 0; ix < kSWITCH_COUNT; ix++)
[binarystring appendFormat:@"%d", !!switches[ix].isOn];
long decimalValue = strtol([binarystring UTF8String], NULL, 2);
NSLog(@"Encoded: 0x%lx", decimalValue);
}
此方法有效,但它是一种相当迂回的获取结果的方法 - 你有 5 个整数(布尔)值,你想将它们组合成一个整数,为什么涉及字符串?
更好的解决方法:使用整数
(Objective-)C 提供按位运算符来执行移位、或、与等操作,这些操作将整数类型视为有序的位集合——这就是它们在计算机上的含义。
<<
运算符左移,例如0x1 << 1
产生 0x2
,即 << 1
相当于乘以 2。|
运算符是按位或,例如0x1 << 1 | 1produces
0x3`。您的问题的答案现在很容易得出:
- (void) shiftMethod
{
unsigned int encoded = 0;
for (int ix = 0; ix < kSWITCH_COUNT; ix++)
encoded = (encoded << 1) | !!switches[ix].isOn;
NSLog(@"Encoded: 0x%x", encoded);
}
如果你不喜欢 shifts 和 ors 你可以使用乘法和加法:
encoded = encoded * 2 + !!switches[ix].isOn;
上面直接解决了问题,没有转换to/from中间字符串。它恰好也快得多,但是在应用程序的总体方案中,这两种方法都可能不会占用很大一部分执行时间,因此您不应该 select 基于此。
第三条路
如果您希望 set/get 整数的各个位,您可以使用具有位域宽度的 struct
类型。这些可以让您直接 set/get 整数的位 - 不需要移位等 - 您可能会发现它们很有用,但它们更像是 "low level"。任何一本关于 C 的好书都会告诉你如何使用这些。
HTH