ios - 在切换案例中声明UI对象

标签 ios objective-c scope switch-statement declaration

我已经了解了切换用例的范围,包括跳转标签和所有这些,但是SO此处建议的解决方案似乎暗示着添加大括号可以解决这个问题。但是,这似乎仍然不起作用:

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语句来完成此操作?

2015年5月23日:一直尝试许多不同的方法以取得成功。

编辑:实施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的所有属性,因此会出现错误:

在类型'UIView *'的对象上找不到属性'text'

即使是Zil的建议,也没有为(UILabel*)[[UILabel alloc]init];类型添加前缀的建议。

有人得到这个工作吗?

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中范围的规则非常简单。每当您输入一对花括号时,您都将输入新的范围。在该范围内声明的任何变量仅存在于该范围内。当退出括号时,该变量将不复存在。

开关内的个别情况不需要括号,因此它们不需要定义局部作用域,但是整个switch语句确实使用括号,因此也定义了局部作用域。在switch语句的花括号内声明的任何变量在花括号外都不存在。

当您输入新的作用域级别时,您可以访问在父作用域中声明的所有内容。

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

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

如果要访问子类的属性,则必须将变量强制转换为适当的类型:

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

编辑

我发现强制转换语法很难输入,并且可能会造成混淆。有时,创建对象实际类型的新临时变量,执行您需要做的所有事情然后将其分配给目标变量,这样会更清楚:
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基类的属性,除非将变量强制转换为特定类型,如上所示。

(请注意,上面的名称“control”是一个不好的选择,因为标签不是控件。最好使用“aView”之类的名称,该名称表示变量中所有对象的通用类。)

关于ios - 在切换案例中声明UI对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30368589/

相关文章:

android - 如何使用 FCM 从 Firebase 控制台发送按钮按下时的自动消息?

ios - '(@lvalue Int) -> $T 7' is not identical to ' 字典 <Int,Int>'

ios - ScrollView 中的 WKWebView

java - 变量 [x] 已在方法 [y] 中定义 - 但范围不同

ios - 以编程方式约束彼此相邻的 3 个 View

ios - 类似于 CGPoint 的类,但带有整数(用于表示网格中的位置)

objective-c - 找不到 Cocoapods 框架

ios - 将 NSAttributedString 转换为 HTML 字符串

jquery - document.ready 中声明的函数未定义?

c++ - 嵌套 while 循环中的范围变量