Bir projeyi ARC'ye dönüştürürken “anahtarlama durumu korumalı kapsamda” ne demektir?


283

Bir projeyi ARC'ye dönüştürürken "anahtarlama durumu korunan kapsamdadır" ne anlama gelir? Xcode 4 Düzenle -> Refactor -> Objective-C ARC dönüştürmek kullanarak bir proje ARC kullanmak için dönüştürüyorum ... Aldığım hatalardan biri "anahtar" korumalı kapsamda "anahtarları" bazı " bir anahtar kutusu.

Düzenle, İşte kod:

HATA "varsayılan" durumda işaretlenir:

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

Yanıtlar:


651

Her kasanın kendisini diş telleriyle çevreleyin {}. Bu sorunu düzeltmelidir (projelerimden birinde benim için yaptı).


12
Parantez derleyicinin kapsamı anlamasına yardımcı olur. Diş telleri olmadan bir vaka ifadesinin ilk satırında yeni bir değişken beyan ettiyseniz GCC'nin bir uyarı yayınladığını biliyorum ve ARC'deki WWDC 2011 videosu, vakaları parantez içine almakla ilgili bir şeyden bahsediyor. Nedenini bilmek istiyorsanız, şu videoya göz atın — Başımın üstünü hatırlayamıyorum.
FeifanZ

87
Bir süre oldu, ama kod gerçekten bir blok içinde değil çünkü bir durumda deyimi sonra değişken atama izin vermedi C standardında bir şey hatırlıyorum gibi görünüyor. Önce ve {...}sonra kıvırcık ayraçlar ekleyerek , içerideki her şey kapsamlı bir blokta ve beklendiği gibi davranacaktır. Bu tür bir problemden kaçınmak için ifadelerimden otomatik olarak bir blok oluşturduğum noktaya geldim . casebreakcase
Paul

2
Ben de aynı sorunla karşılaştım. Bu korkunç bir hata mesajı ve düzeltmek için bir hata (derleyicinin gelecekteki bir sürümünde düzeltilecek) dosyalandı. Ancak, evet, C'deki vaka ifadelerindeki kapsam belirleme kuralları gerçekten çok garip.
bbum

59
Bu, bir vaka kapsamında yeni bir değişken bildirdiğiniz için gerçekleşiyor. Derleyici, bu değişkenin nasıl kapsaması gerektiğini bilmiyor (tüm anahtar durumlarına mı yoksa sadece şu anki duruma mı ait?) Kasanın uygulamasını parantez içine almak, değişkenin içinde yaşaması için bir kapsam oluşturur, böylece derleyici düzgün bir şekilde yönetebilir ömür boyu.
Shinohara

1
Bu durumun, kaşlı ayraç içermeyen bir vaka deyimi içindeki bir blok içindeki bir değişkeni bildirirken de olabileceğini unutmayın. Bir iki dakikalığına kafa kaşıyıcıydı. =)
slycrel

14

Koda bakmadan emin olmak zor, ama muhtemelen anahtarın içinde bazı değişken bildirimler var demektir ve derleyici gerekli dealloc noktasına net bir yol olup olmadığını söyleyemez.


9

Bu sorunu çözmenin 2 kolay yolu vardır:

  • Muhtemelen değişkenler beyan ediyorsunuz. Değişkenlerin bildirimini switch deyiminin dışına taşıma
  • Tüm kasa bloğunu süslü parantezler arasına koyun {}

Değişkenler serbest bırakıldığında derleyici kod satırını hesaplayamaz. Bu hataya neden oluyor.


5

Benim için sorun, bir anahtarın ortasında başladı ve {} IN ALL önceki durum ifadelerini eklemeniz gerekmedikçe, süslü parantezler işe yaramadı. Benim için hata ifadeyi aldığımda geldi

NSDate *start = [NSDate date];

önceki durumda. Bunu sildikten sonra, sonraki tüm vaka bildirimleri korunan kapsam hata mesajından temizlendi


Aynı şey; ortada durum hatası. Sadece değişken bildirimini anahtarın üstüne taşımak zorunda kaldım (büyük / küçük harf bağımlı değil). Olguların etrafına parantez eklemek zorunda kalmadım (bu sefer).
eGanges

3

Önce:

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

Geçişten önce NSDate tanımını taşıdım ve derleme sorununu düzeltti:

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

}

2

Değişkenleri anahtarın dışında belirtin, sonra bunları kasanın içine yerleştirin. Bu Xcode 6.2 kullanarak benim için mükemmel çalıştı


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

Not: Kontrol edin! Kalın ve italik çizginin sözdizimi. Düzelt ve sen gitmeye hazırsın.


0

Surround ile çevrelemek her bir durumda case deyimi ve break arasındaki {}kodu destekler . Kodum üzerinde çalıştı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.