如何检查可变参数列表中的int?

时间:2011-09-23 08:19:46

标签: objective-c

我有一个方法可以采用可变数量的参数。

我正在使用variadic命令来获取参数并将它们存储在NSMutableDictionary中。

问题是,如果我向方法发送一个int,我会崩溃,因为NSMutableDictionaries无法存储int。

我想要做的是让方法检查其中一个参数是否为int,如果是,则在将其放入字典之前将其转换为NSNumber。

但我不能为我的生活找到如何检查int。

[我知道一个答案是“不要向方法发送一个int,只发送NSNumbers!”问题是,这对方法的调用者施加了一个无法单独从方法描述中确定的义务。]

3 个答案:

答案 0 :(得分:3)

无法检查可变参数列表中的参数类型。它必须以其他方式指定。

例如,NSLog()使用format参数获取类型信息:对象为%@,整数值为%d,浮点值为%f

答案 1 :(得分:3)

我最近在Apple doc中遇到了概念"Type Encodings"。这是使用 @encode() 编译器指令完成的。 Doc说,“当给出类型规范时,@ encode()返回一个字符串,编码类型为”

所以,唱 @encode() typeof() strcmp () 我们可以找到传递的变量的类型。 typeof()返回变量的类型。例如, @encode(int)返回“i”并认为名为 var 的变量是一个整数变量,然后 typeof( var)将返回 int 。在这种情况下, @encode(int) @encode(typeof(var))将仅返回“i”。我们可以使用 strcmp()方法检查字符串是否相等。

if (strcmp(@encode(typeof(variable)), @encode(int)) == 0) {

    // The varibale is an "int"
    // @encode(int) returns "i"

    // @encode(float) returns "f"
    // @encode(double) returns "d"

} else if (strcmp(@encode(typeof(variable)), @encode(NSObject *)) == 0) {

    // The varibale is an "object"
    // @encode(NSObject *) returns "@"
    // You can use anything in the place of NSObject in the above line
    // @encode(NSString *) or @encode(UIButton *) will also return "@"
}

列出了所有Objective-C类型编码的列表。您可以在上面的Apple doc链接中检查其他类型的字符串编码。

在可变函数中应用上述概念几乎不可能将上述类型编码概念用于具有不同类型参数的可变参数,因为我们得到仅在将类型指定为参数后,才从va_arg()方法获取每个参数。因此,我们试图让参数从va_arg()方法中找到它的类型,该方法本身需要返回参数的类型。有点恼火!

答案 2 :(得分:1)

编辑:这不起作用。我以为是,但现在我遇到崩溃,我不明白。如果我弄清楚,我会更多地编辑它。这是我之前写的,这是错的。再次,这不起作用:

  

我想我找到了答案:键值编码。

     

使用键值编码,我可以设置id类型的实例变量,   然后动态识别变量的实际内容。一世   可以放任何东西,甚至是int,而Key-Value方法也会   为我识别它。但更令人敬畏的是,如果我   使用键值编码来检索变量的内容,并使用   变量结果为int,键值编码自动转换   它对我来说是一个NSNumber。

     

我将尝试演示。

     

主要是为变量I设置访问器语句   想要访问。所以,对于这个例子,让我们说变量是   称为“identifyMe。”

//in the interface:
@property (copy) id accessIdentifyMe;

//in the implementation:
@synthesize accessIdentifyMe = identifyMe;
     

现在“identifyMe”符合键值。我们很高兴。

     

我所要做的就是获取可变参数列表中的项目,然后传递它们   逐个识别我,并使用键值方法来识别   内容。像这样:

/*...assume all the following is happening inside a loop that
     

重复       可变列表。我将调用可变参数列表“variadicList”。   首先,我接受       当前的可变参数项并将其放入identifyMe中,声明它   作为类型       “ID”*/       identifyMe = va_arg(variadicList,id);

/*Now I use a Key-Value method to check if identifyMe holds an
     

的NSNumber。如果它       持有一个int,它会自动返回为NSNumber,   你会记得,所以       查询NSNumber在功能上与查询相同   一个int。
      在循环之外我设置了一个名为foundANumber的方便布尔值   在哪...       存储查询结果:* /       foundANumber = [[self valueForKey:@“identifyMe”]   isKindOfClass:[NSNumber class]];

     

这使我能够将数字与对象分开。   完成后,我可以将对象直接放入我的字典中,并且   在将数字放入字典之前,将数字放入NSNumber中。

     

这在另一端意味着什么时候调用这个方法   另一个对象,就是我可以调用这个方法并在其中放入一个int   参数列表,不用担心导致崩溃。耶。

这是不起作用的原因:KVC不是魔术。我认为它有一些超级特殊的方法来确定变量的类型,但事实并非如此。它只是查看访问器方法中声明的类型,并且它不能独立地验证。该死。