Під час перетворення проекту на використання ARC, що означає "корпус перемикання знаходиться в захищеному просторі"?


283

При перетворенні проекту на використання ARC, що означає "корпус комутації знаходиться в захищеному просторі"? Я перетворюю проект на використання ARC, використовуючи Xcode 4 Edit -> Refactor -> Перетворити в ARC Objective-C ... Однією з помилок, які я отримую, є "випадок перемикання в захищеній області" на "деякі" комутатори в корпус вимикача.

Редагувати, ось код:

ПОМИЛКА позначена у випадку "за замовчуванням":

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

Обведіть кожен корпус самим брекетами {}. Це має вирішити це питання (це було для мене в одному з моїх проектів).


12
Дужки допомагають компілятору зрозуміти область застосування. Я знаю, що GCC використовував для видачі попередження, якщо ви оголосили нову змінну в першому рядку заяви справи без дужок, а відео WWDC 2011 на ARC згадує щось про укладання справ у дужки. Якщо ви хочете знати, чому це, перегляньте це відео - я не можу згадати вгорі голови.
FeifanZ

87
Минуло деякий час, але, схоже, я пам’ятаю щось у стандарті C, яке не дозволяло присвоювати змінну після заяви справи, оскільки код насправді не знаходиться в блоці. Додаючи фігурні фігурні дужки {...}після caseта перед break, все все знаходиться в загальному блоці та буде вести себе так, як очікувалося. Я дійшов до того, що я автоматично автоматично блокую свої caseзаяви, щоб уникнути подібних проблем.
Пол,

2
Я зіткнувся з тим же питанням. Це жахливе повідомлення про помилку, і помилка була подана (яка буде виправлена ​​у майбутній версії компілятора) для її виправлення. Але, так, правила визначення обсягу у твердженнях про випадки в С справді є дуже ... дивними.
bbum

59
Це трапляється, оскільки ви декларуєте нову змінну в межах справи. Компілятор не знає, як слід застосовувати цю змінну (чи належить вона до всіх випадків комутаторів або лише до поточного випадку?), Загортаючи реалізацію корпусу в дужки, створює область для змінної в межах, щоб компілятор міг правильно керувати це все життя.
Shinohara

1
Зауважте, що це також може статися при оголошенні змінної в блоці в операторі справи без фігурних дужок. Це була дряпалка голови протягом хвилини-двох. =)
slycrel

14

Важко бути впевненим, не дивлячись на код, але це, ймовірно, означає, що всередині комутатора відбувається декларація змінної, і компілятор не може визначити, чи є чіткий шлях до потрібної точки взаємодії.


9

Є два прості способи вирішити цю проблему:

  • Ви, ймовірно, декларуєте змінні. Перемістіть декларацію змінних за межами оператора switch
  • Поставте весь блок корпусу між фігурними дужками {}

Компілятор не може обчислити рядок коду, коли змінні слід випустити. Викликання цієї помилки.


5

Для мене проблема почалася з середини комутатора, і фігурні дужки не випрацювали, якщо тільки вам не доведеться включати {} ВСІ попередні заяви справи. Для мене помилка виникла, коли у мене була заява

NSDate *start = [NSDate date];

у попередньому випадку. Після того, як я видалив це, все наступне твердження справи видалялось із повідомлення про помилку захищеного діапазону


Однакові речі; випадок помилки в середині. Мені довелося лише перемістити декларацію змінної над комутатором (це не залежно від регістру). Мені не довелося додавати дужки навколо справ (цього разу).
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

Обведіть дужками {}код між випискою справи та перервою у кожному випадку. Це працювало на моєму коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.