我有一个方法可以采用可变数量的参数。
我正在使用variadic命令来获取参数并将它们存储在NSMutableDictionary中。
问题是,如果我向方法发送一个int,我会崩溃,因为NSMutableDictionaries无法存储int。
我想要做的是让方法检查其中一个参数是否为int,如果是,则在将其放入字典之前将其转换为NSNumber。
但我不能为我的生活找到如何检查int。
[我知道一个答案是“不要向方法发送一个int,只发送NSNumbers!”问题是,这对方法的调用者施加了一个无法单独从方法描述中确定的义务。]
答案 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不是魔术。我认为它有一些超级特殊的方法来确定变量的类型,但事实并非如此。它只是查看访问器方法中声明的类型,并且它不能独立地验证。该死。