6

我有一个方法,我正在传递一个变量的参数列表。我isKindOfClass为字符串等做。但是如何确定 ivar 是否为 BOOL?

4

2 回答 2

4

不,不是在运行时。BOOL 是原始类型,而不是类。实际上 BOOL 是一个有符号的字符。

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

作为一种解决方法,您可以将 BOOL 包装在 NSNumber 中以从中生成 Obj-C 对象。然后您可以进行运行时检查:

NSNumber * n = [NSNumber numberWithBool:YES]; // @(YES) in Xcode 4.4 and above
if (strcmp([n objCType], @encode(BOOL)) == 0) {
    NSLog(@"this is a bool");
} else if (strcmp([n objCType], @encode(int)) == 0) {
    NSLog(@"this is an int");
}

编辑:此代码可能不适用于 BOOL,因为它在内部编码为 char 。请参阅此答案以获取替代解决方案:https ://stackoverflow.com/a/7748117/550177

于 2012-07-30T10:34:10.220 回答
0

键值编码可能可以帮助您解决这个问题。有一些原语(例如valueForKey:)能够检查对象的 ivars 并执行内置函数的转换。从这个意义上说,您可以将(ivar 名称作为字符串)传递给函数,并让系统执行NSNumber类型为 C 原语的转换。当然,这会引入一些开销。

您也可以使用 objc 运行时来解决此问题,但 KVC 可能会做您需要的事情,而无需求助于使用 objc 运行时(您自己)。

如果要确定va_list 参数是否为 a BOOL,则需要指定它(这就是需要格式说明符的原因)。在某些情况下,您看到的替代方案是-[NSArray initWithObjects:...]——在这种情况下,初始化程序需要每个参数的 objc 对象,以及零终止;您需要进行BOOL-> 对象提升。

备选方案:C++ 可以为您提供所有这些类型的信息(例如,使用模板)。

于 2012-07-30T11:28:16.073 回答