我在一种语法中感到困惑,只想知道以下两种语法之间的不同。
#define objKeys @[@"key1",@"key2",@"key3"]
#define dicWithValue1(val1,val2,val3) [NSMutableDictionary dictionaryWithObjects:@[val1,val2,val3] forKeys:objKeys]
#define dicWithValue2(objArray) [NSMutableDictionary dictionaryWithObjects:objArray forKeys:objKeys]
-(void)someFunction
{
NSMutableArray *arrValues = [[NSMutableArray alloc] init];
[arrValues addObject:dicWithValue1(@"val1",@"val2",@"val3")]; // STATEMENT 1
[arrValues addObject:dicWithValue1(@[@"val1",@"val2",@"val3"])]; // STATEMENT 2
// Below Statements will give error... for Multiple Arguments..
[arrValues addObject:dicWithValue2(@"val1",@"val2",@"val3")]; // STATEMENT 3
[arrValues addObject:dicWithValue2(@[@"val1",@"val2",@"val3"])]; // STATEMENT 4
}
问题1:语句2将在运行时崩溃应用程序,但它在编译时没有给出任何错误。那么,Statement 1和Statement 2有什么区别?
问题2:我们如何在#define函数中传递数组对象,如语句3和4为多个参数提供编译错误。
答案 0 :(得分:3)
首先提示,您可以使用gcc -E在文件上运行预处理器,这将扩展您的所有宏,以便您可以轻松查看问题所在:
gcc -E -o outfile.m myFile.m
如果您使用已编写的代码将其放入文件并运行此命令,则会收到有关您的问题的所有错误消息。如果您对错误消息有疑问,可以问问他们。
您已经陷入了一些您正在做的事情,因为宏无法忽略逗号。所以@[@"val1",@"val2",@"val3"]
将三个参数传递给宏,即arg1:@[@"val1"
arg2:@"val2"
arg3:@"val3"]
你可以通过括号来解决这个问题:
(@[@"val1", @"val2", @"val3"])
[arrValues addObject:dicWithValue2((@[@"val1",@"val2",@"val3"]))]; \\Statement 4
Here's包含逗号问题部分的文档。
答案 1 :(得分:0)
问题1:
语句2将崩溃,因为您有不同数量的键和值。编译器不知道数组中的元素数量应该相等而且无法找到;因此,这是一项只能在运行时强制执行的要求。
问题2:
我真的不明白给定的问题语句1已经显示了如何从编译器常量传递as数组。我建议你避免使用这些复杂的宏,因为它们可能比它们的价值更麻烦。
答案 2 :(得分:0)
问题1:
dicWithValue1期待三个值。
语句1执行此操作,但语句2不执行(它传递一个值为3个对象的数组)。
您可以使用Statement 1或Statement 4。
问题2:
什么是编译错误说明?
您可能需要在此处投放objArray
数组:dictionaryWithObjects:objArray
答案 3 :(得分:0)
我认为@trojanfoe是对的。
回答1:
语句2将失败,因为在运行时之前未定义参数数量,因为您只传递一个参数而不是三个参数,它仍然会崩溃。
回答2:
声明3由于与上述相同的原因而不正确,即您传递的参数数量无效。 语句4也不起作用,因为直到运行时才定义参数数量。
但是,您可以尝试使用此代码使其正常工作:
NSArray* tempArray= [[NSArray alloc] initWithObjects:@"abc", @"def", @"ghi", nil];
[arrValues addObject:dicWithValue2(tempArray)];
答案 4 :(得分:0)
我认为答案在于编译器如何解析参数数据类型和宏声明中参数数量的机制。我不是这个主题的专家,但似乎编译器在编译时解决函数的参数没有问题。
在语句2中,如果减少/增加1个参数,编译器将为不匹配的参数抛出错误。虽然它只是一个参数,并且在运行时因崩溃而被确认,因为剩下的两个参数是nil
。 Statement2没有提供函数期望的确切参数。这就是崩溃的原因。
出于同样的原因,编译器无法计算语句3和4中的参数计数。
就您的问题2解决方案而言,您可以通过创建本地数组对象并将其作为参数传递,将NSArray
对象传递给macro
。请参阅以下代码: -
NSArray * arrNewValues = @[@"val1",@"val2",@"val3"];
[arrValues addObject:dicWithValue2(arrNewValues)];
这样你就可以通过完全匹配参数来使编译器沉默。