gpt4 book ai didi

iphone - Obj-C 中奇怪的开关错误

转载 作者:太空狗 更新时间:2023-10-30 03:15:10 27 4
gpt4 key购买 nike

我的代码中有这个 switch 语句:

switch(buttonIndex){
case 0:
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
break;
case 1:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:[imagePicker autorelease] animated:YES];
break;
default:
[self openEmailViewInViewController:self];
}

在案例 1 的 UIImagePickerController 实例化中,我收到一个错误:
error:expected expression before 'UIImagePickerController'

我不知道我做错了什么。想法?

哦,buttonIndex 是一个 NSInteger

最佳答案

我遇到了这个问题,有一天我决定深入研究它。

简短的非回答但务实的解决方案:

解决这个“问题”的一种方法是使用分号,; , 紧跟在 case ...: 的冒号之后陈述。例如,使用您提供的示例,它可以是“固定的”,因此它的编译和行为就像您直觉上期望的那样:

    case 1:; // <- Note semi-colon.
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

长答案:

一些历史:以前,C 只允许您在 block 的开头声明“ block 局部”变量,然后是各种语句。 C99 改变了一些东西,所以你可以自由地混合变量声明和语句。

在 C99 BNF 文法的上下文中,变量声明是 declaration , 语句是 statement . A statement意味着多种事物,其中之一被称为 compound-statement ,就是熟悉的 { ... }堵塞。 ...部分松散地定义为 zero or more block-items , 带有 block-item被松散地定义为 either a declaration or a statement .

问题出在 labeled-statement的方式上(一个 goto 标签、case 标签或 default:,本质上是 ...: 语句)被定义,它是松散定义的 ...: zero or more statements .正如人们直觉所料,它不是 zero or more statements or declarations .使用 ;紧跟在 labeled-statement 之后s :基本上终止了 zero or more statements labeled-statement 的一部分.这会导致语法回退到 compound-statement定义,它允许下一个“语句”是 statementdeclaration .

我没有调查这是否是对 C99 语言规范的无意疏忽(实际上,C99 标准中的一个错误),或者这是否是对编写语言语法的复杂性的务实让步。如果您不熟悉编写语法,您会注意到上面的解释允许递归:A labeled-statement可以匹配 case 1: case 2: case 3: .用过于简单的术语 (1) ,某些类型的语法递归简单且“无歧义”,而另一些则复杂且“有歧义”。为简单起见,大多数语言工具只会处理必须通过查看“下一个标记”来确定性地解决任何歧义的情况。我提到这一点只是因为虽然这在直觉上看起来像是 C99 规范中的一个缺陷,但可能存在令人信服的、非显而易见的原因......而且我没有费心对该主题进行任何进一步的研究以找出无论哪种方式。
(1)这并不是技术上准确的描述,而是对于不熟悉所涉及问题的人的合理近似。

编辑:

我给出的解决方案适用于“大多数”情况(情况是“用法”,而不是 switch case s),但在一种情况下确实失败:当声明声明 C99 variable length array 时,这将不起作用,例如 case 1:; void *ptrs[count];这是因为在 C99 中,“跳过”C99 VLA 的声明是错误的,该声明位于发生跳转的同一词法范围内。在这些情况下,您需要使用 case 1: { void *ptrs[count]; } .在这种情况下, ptrs 的范围VLA 在收盘时结束 } .这比最初看起来更复杂,因为以下是完全合法的 C 代码,尽管乍一看,人们会直觉地认为它不是:
switch(3){
case 0:
printf("case 0\n");
break;
case 1:;
int *ip = NULL;
printf("case 1\n");
break;
case 2:
{
int ia[6];
printf("case 2\n");
break;
case 3:
printf("case 3\n");
break;
default:
printf("default\n");
}
}

这将编译,并在运行时打印 case 3 .

另见: Wikipedia: Duffs Device

关于iphone - Obj-C 中奇怪的开关错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1180550/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com