2011-09-26 10 views
281

Al convertir un proyecto para usar ARC, ¿qué significa "cambiar de mayúscula a minúscula en ámbito protegido"? Estoy convirtiendo un proyecto para usar ARC, usando Xcode 4 Edición -> Refactor -> Convertir a Objective-C ARC ... Uno de los errores que obtengo es "el caso del interruptor está en alcance protegido" en "algunos" de los conmuta en una caja de interruptor.Al convertir un proyecto para usar ARC, ¿qué significa "Cambiar caso está en ámbito protegido"?

Editar, Aquí está el código:

el error está marcado en el caso "default":

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

Respuesta

653

Rodean cada caja con llaves {}. Eso debería solucionar el problema (lo hice por mí en uno de mis proyectos).

+20

¡Guau! ¡Funcionó! ¡¿pero por qué?! – Ali

+12

Las llaves ayudan al compilador a entender el alcance.Sé que GCC solía emitir una advertencia si declaraba una nueva variable en la primera línea de una declaración de caso sin llaves, y el video WWDC 2011 en ARC menciona algo acerca de incluir casos entre llaves. Si quieres saber por qué, echa un vistazo a ese video. No puedo recordarlo. – FeifanZ

+87

Ha pasado un tiempo, pero parece recordar algo en el estándar C que no permitía la asignación de variables después de una declaración de caso porque el código no está realmente dentro de un bloque. Al agregar llaves {'...}' después del 'case' y antes del' break', todo lo que está dentro se encuentra en un bloque de ámbito y se comportará como se espera. He llegado al punto de que simplemente hago un bloque de mis declaraciones 'case' para evitar este tipo de problema. – Paul

14

difícil estar seguro sin mirar el código, pero probablemente significa hay alguna declaración de variable dentro del interruptor y el compilador no puede decir si hay una ruta clara al punto de dealloc requerido.

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

Nota: ¡Compruebe! La sintaxis de la línea en negrita &. Rectifícalo y estás listo para ir.

5

Para mí, el problema comenzó en el medio de un interruptor y las llaves no funcionó, a menos que tenga que incluir {} EN TODAS las declaraciones de casos anteriores. Para mí el error vino cuando tuve la declaración

NSDate *start = [NSDate date]; 

en el caso anterior. Después de que he eliminado esto, entonces todos Declaración caso posterior llegó limpia a partir del mensaje de error ámbito protegido

+0

Lo mismo; error de caso en el medio. Solo tuve que mover la declaración de la variable por encima del interruptor (no dependía de la caja). No tuve que agregar llaves alrededor de los casos (esta vez). – eGanges

3

Antes:

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

Me moví NSDate definición antes del interruptor, y se solucionó el problema de compilación:

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

} 
9

Hay 2 maneras fáciles de resolver este problema:

  • Usted probablemente está declarando variab les. Mover la declaración de las variables fuera de la instrucción switch
  • Ponga todo el bloque en caso entre llaves {}

El compilador no puede calcular la línea de código cuando las variables son para ser lanzado. Causando este error.

2

Declara las variables fuera del interruptor, y ejemplifícalas dentro de la caja. que funcionó perfectamente para mí usando Xcode 6.2

0

envolvente con los apoyos {} el código entre las caso declaración y la ruptura en cada caso. Funcionó en mi código.

Cuestiones relacionadas