プロジェクトをARCを使用するように変換する場合、「switch case is in protected scope」とはどういう意味ですか?


283

ARCを使用するようにプロジェクトを変換する場合、「switch case is in protected scope」とはどういう意味ですか?Xcode 4の[編集​​]-> [リファクタリング]-> [Objective-C ARCに変換]を使用して、プロジェクトをARCを使用するように変換しています...発生するエラーの1つは、スイッチケース。

編集、これがコードです:

エラーは「デフォルト」の場合にマークされます。

- (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;
}

回答:


651

各ケース自体を中括弧で囲みます{}。これで問題が解決するはずです(私のプロジェクトの1つで解決しました)。


12
中括弧は、コンパイラーがスコープを理解するのに役立ちます。かっこなしでcaseステートメントの最初の行で新しい変数を宣言した場合、GCCが警告を発行していたことを知っています。ARCのWWDC 2011ビデオでは、かっこでケースを囲むことについて言及しています。理由を知りたい場合は、そのビデオをチェックしてください。頭の上を思い出せません。
FeifanZ 2011

87
久しぶりですが、コードが実際にはブロックの内部にないため、Cステートメントの中で、Caseステートメントの後に変数を割り当てることができないものを覚えているようです。の前との前に中かっこを追加{...}するcasebreak、内部のすべてがスコープブロックになり、期待どおりに動作します。caseこの種の問題を回避するために、ステートメントを自動的にブロックするようになりました。
ポール

2
同じ問題に遭遇しました。これは恐ろしいエラーメッセージであり、それを修正するためにバグが提出されています(これはコンパイラの将来のバージョンで修正される予定です)。しかし、はい、Cのcaseステートメント内のスコープ規則は本当に非常に奇妙です。
bbum 2011

59
これは、ケースのスコープ内で新しい変数を宣言しているために発生しています。コンパイラーは、この変数をどのようにスコープする必要があるかを知りません(それはすべてのスイッチケースに属しますか、それとも現在のケースだけに属しますか?)ケースの実装をブラケットでラップすると、変数がスコープ内に存在するため、コンパイラーは適切に管理できますそれは生涯です。
篠原

1
これは、中括弧のないcaseステートメント内のブロック内で変数を宣言するときにも発生する可能性があることに注意してください。それは1〜2分頭を悩ませるものでした。=)
slycrel 2014年

14

コードを見ないで確認するのは難しいですが、おそらくスイッチ内で変数宣言が行われていて、コンパイラーは必要な割り当て解除ポイントへの明確なパスがあるかどうかを判断できません。


9

この問題を解決するには、2つの簡単な方法があります。

  • おそらく変数を宣言しています。変数の宣言をswitchステートメントの外に移動します
  • ケースブロック全体を中括弧{}の間に置きます

変数が解放されるとき、コンパイラーはコード行を計算できません。このエラーの原因。


5

私にとって、問題はスイッチの途中で始まり、前のすべてのケースステートメントに{}を含める必要がない限り、中括弧は機能しませんでした。私にとってエラーは私が声明をしたときに来ました

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;
    }

注:確認してください!太字および斜体の行の構文。それを修正し、あなたは行ってもいいです。


0

ケースステートメントと各ケースのブレークの{}間のコードを中括弧で囲みます。それは私のコードで動作しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.