在 Switch Case 中声明 UI 对象 [英] Declaring UI Objects in Switch Cases

查看:26
本文介绍了在 Switch Case 中声明 UI 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了关于 switch 案例的范围,即 跳转标签 等等,但是这里建议的解决方案似乎暗示添加花括号可以规避这个问题.但是,这似乎仍然不起作用:

I've read about the scope of switch cases, being jump labels and all, but the suggested solutions here at SO seem to imply that adding curly braces would circumvent the issue. However, this still doesn't seem to work:

switch (objectType) {

  case label:   //label is an integer constant
    NSLog(@"statement before declaration");
    UILabel *control = [[UILabel alloc] init];       //no error
    break;

  case button:  //button is an integer constant
    {
      UIButton *control = [[UIButton alloc] init];   //no error
    }
    break;    

  default:
    break;
}

// error when trying to use the *control* variable,
// Use of undeclared identifier 'control'

有没有什么方法可以用 switch 语句来完成这个?

Is there any way to accomplish this with switch statements?

2015 年 5 月 23 日:尝试了许多不同的方法都没有成功.

23rd May 2015: been trying many different approaches to no success.

实施 Cyrille 建议的解决方案时出错:

UIView *control = nil;
switch (objectType)
{
  case label:  //button is an integer constant
    {
      control = [[UILabel alloc] init];   //no error

      //error: property 'text' not found on object of type 'UIView *'
      control.text = @"Something...";     
    }
    break; 

  default:
    break;
}

显然,即使从UIView重铸为UILabel,对象也没有继承UILabel的所有属性,因此报错:

Apparently, even after being recast from UIView to UILabel, the object did not inherit all the properties of UILabel, and thus the error:

在UIView *"类型的对象上找不到属性文本"

甚至 Zil 建议在类型 (UILabel*)[[UILabel alloc]init]; 前加上前缀也没有奏效.

Even Zil's suggestion to prefix the type (UILabel*)[[UILabel alloc]init]; did not work.

有人让这个工作吗?

DUNCAN C. 的解决方案 (请参阅下面接受的答案)

    UIView *control = nil;
    switch (objectType)
    {
        case label:  
            control = [[UILabel alloc] init];
            ((UILabel *)control).text = @"Something...";     
            break; 

        default:
            break;
    }

    // UI object instantiated inside switch case recognised!
    ((UILabel *)control).textColor = [UIColor redColor];

谢谢邓肯 C.

推荐答案

Objective-C 中的作用域规则非常简单.任何时候你输入一对花括号,你就进入了一个新的范围.在该范围内声明的任何变量仅存在于该范围内.当你退出大括号时,变量不再存在.

The rules for scope in Objective-C are pretty simple. Any time you enter a pair of curly braces, you enter a new level of scope. Any variable declared inside that scope only exists inside that scope. When you exit the braces, the variable ceases to exist.

switch 中的各个 case 不需要大括号,因此它们不定义局部级别的范围,但整个 switch 语句确实使用大括号,因此它确实定义了局部范围范围.在 switch 语句的大括号内声明的任何变量都不存在于大括号外.

The individual cases inside a switch don't need braces, so they don't define a local level of scope, but the entire switch statement does use braces, and so it does define a local scope. Any variable declared inside the switch statement's braces doesn't exist outside the braces.

当您进入一个新级别的范围时,您可以访问在您的父范围中声明的所有内容.

When you enter a new level of scope you have access to everything declared in your parent scope.

你没有完全清楚你想要做什么.我THINK你想要做的是拥有一个父类的变量,然后将来自子类的新对象放入其中,并且仍然可以访问子类的独特属性.

You don't make it completely clear what it is you want to do. I THINK what you want to do is have a variable of a parent class, and then put new objects in it that are from subclasses, and still have access to the unique properties of the child class.

如果您声明一个基类的变量,您可以将属于该类型的子类的任何对象分配给该变量.

If you declare a variable of a base class, you can assign any object that is a subclass of that type to the variable.

如果你想访问子类的属性,通过,你必须将变量转换为适当的类型:

If you want access to the properties of the subclass, through, you have to cast the variable to the appropriate type:

UIView *control = nil;
switch (objectType)
{
  case label:  
    control = [[UILabel alloc] init];   //no error

    ((UILabel *)control).text = @"Something...";     
    break; 
  case button: 
    control = [UIButton buttonWithType: UIButtonTypeSystem];
    [((UIButton *)control) setTitle: "Foo" forState: UIControlStateNormal];
  default:
    break;
}

编辑

我发现强制转换语法很难输入,而且会让人感到困惑.有时创建对象实际类型的新临时变量会更清楚,做任何你需要做的事情,然后将其分配给目标变量,如下所示:

EDIT

I find the casting syntax to be a pain to type, and it can get confusing. Sometimes it's clearer to create a new temporary variable of the object's actual type, do whatever you need to do, and then assign it to the target variable, like this:

UIView *control = nil;
switch (objectType)
{
  case label:  
    UILabel *aLabel = [[UILabel alloc] init];   //no error

    aLabel.text = @"Something...";   
    aLabel.someOtherProperty = someOtherValue;
    control = aLabel;  
    break; 
  case button: 
    UIButton aButton = [UIButton buttonWithType: UIButtonTypeSystem];
    [aButton setTitle: "Foo" forState: UIControlStateNormal];
    control = aButton
  default:
    break;
}

在 switch 语句之外,您将不知道控制变量包含哪种类型的对象,因此您将只能访问 UIView 基类的属性,除非您强制转换变量到具体的类型,如上图.

Outside the switch statement, you won't know which type of object the control variable contains, so you will only be able to access the properties of the UIView base class, unless you cast the variable to the specific type, as shown above.

(请注意,上面的名称控件"是一个错误的选择,因为标签不是控件.最好使用像aView"这样的名称,它暗示可能在变量中的所有对象的公共类.)

(Note that the name "control" above is a bad choice, since a label is not a control. Better to use a name like "aView" that implies the common class of all objects that might be in the variable.)

这篇关于在 Switch Case 中声明 UI 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆