将项目转换为使用ARC时,“开关盒在保护范围内”是什么意思?


283

将项目转换为使用ARC时,“开关盒在受保护的范围内”是什么意思?我正在使用Xcode 4编辑->重构->转换为Objective-C ARC,将项目转换为使用ARC ...我得到的错误之一是在“某些”开关中出现“开关大小写在保护范围内”开关盒。

编辑,这是代码:

在“默认”情况下标记为ERROR:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"";
    UITableViewCell *cell ;
    switch (tableView.tag) {
        case 1:
            CellIdentifier = @"CellAuthor";
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.textLabel.text = [[prefQueries objectAtIndex:[indexPath row]] valueForKey:@"queryString"];
        break;
    case 2:
        CellIdentifier = @"CellJournal";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.textLabel.text = [[prefJournals objectAtIndex:[indexPath row]] valueForKey:@"name"];

        NSData * icon = [[prefJournals objectAtIndex:[indexPath row]] valueForKey:@"icon"];
        if (!icon) {
            icon = UIImagePNGRepresentation([UIImage imageNamed:@"blank72"]);
        }
        cell.imageView.image = [UIImage imageWithData:icon];

        break;

    default:
        CellIdentifier = @"Cell";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
        break;
    }


    return cell;
}

Answers:


651

用括号包围每个盒子本身{}。那应该可以解决问题(在我的一个项目中对我来说确实如此)。


12
花括号可帮助编译器了解范围。我知道,如果您在没有大括号的case语句的第一行声明了新变量,GCC就会发出警告,并且ARC上的WWDC 2011视频提到了将大括号括起来的内容。如果您想知道为什么,请查看该视频-我不记得了。
FeifanZ 2011年

87
已经有一段时间了,但是我似乎还记得C标准中的某些情况,该情况不允许在case语句之后进行变量赋值,因为代码实际上不在块内。通过{...}case和之前添加花括号break,其中的所有内容都在作用域内,并且将按预期运行。我已经指出,我只是自动在我的case陈述中添加了一个代码块,以避免此类问题。
保罗

2
我遇到了同样的问题。这是一个可怕的错误消息,并且已提交一个错误(将在以后的编译器版本中修复),以对其进行纠正。但是,是的,C语言中case语句中的作用域规则确实非常……很奇怪。
bbum 2011年

59
发生这种情况是因为您要在案例范围内声明一个新变量。编译器不知道该变量的范围(它属于所有switch案例还是仅属于当前案例?)将案例的实现括在方括号内将创建变量的生存范围,以便编译器可以正确管理这是一生。
筱原2012年

1
请注意,在没有大括号的case语句中的块内声明变量时,也会发生这种情况。那是一两分钟的头挠。=)
slycrel 2014年

14

不用看代码就很难确定,但这可能意味着在开关内部正在进行一些变量声明,并且编译器无法告知是否存在通往所需的dealloc点的清晰路径。


9

有两种简单的方法可以解决此问题:

  • 您可能在声明变量。将变量的声明移到switch语句之外
  • 将整个案例放在大括号{}之间

当要释放变量时,编译器无法计算代码行。导致此错误。


5

对我来说,问题始于开关中间,大括号没有解决,除非您必须在所有先前的case语句中包括{}。对我来说,当我发表声明时,错误就来了

NSDate *start = [NSDate date];

在前一种情况下。删除此内容后,所有后续case语句均会从受保护范围错误消息中清除


一样; 中间出现大小写错误。我只需要将变量声明移到开关上方(与大小写无关)。我这次不必在案件两边加括号。
eGanges

3

之前:

    case 2:
        NSDate *from = [NSDate dateWithTimeIntervalSince1970:1388552400];
        [self refreshContents:from toDate:[NSDate date]];
        break;

我在切换之前移动了NSDate定义,它解决了编译问题:

NSDate *from;  /* <----------- */
switch (index) {
    ....
    case 2:
        from = [NSDate dateWithTimeIntervalSince1970:1388552400];
        [self refreshContents:from toDate:[NSDate date]];
        break;

}

2

在开关外部声明变量,然后在案例中实例化它们。使用Xcode 6.2对我来说效果很好


1
default:
        CellIdentifier = @"Cell";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            ***initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];***
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
        break;
    }

注意:检查!粗体和斜体线的语法。纠正它,您就很好了。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.