斯威夫特:为什么这是不可改变的?

时间:2016-08-20 13:47:23

标签: swift immutability

你能告诉我为什么这段代码不起作用吗?

我有几个[AnyObject]数组包含UILabels和UITextForm。 此func应将参数作为数组,并禁用所有标签和文本表单。我已尝试使用map,但仍然遇到同样的问题,编译器告诉我,或者变量是常量或者是不可变的。

func disableSectionForm(formSection section: inout [AnyObject]) {
    for i in 0...section.count {
        if section[i] is UILabel || section[i] is UITextField {
            section[i].isEnabled = false
        }
    }
}

2 个答案:

答案 0 :(得分:4)

这里有很多编译错误

问题#1(这只是一个建议)

这里不需要

inout,因为你没有改变section数组,而是改变其中的对象。

问题#2

inout应该在param名称之前(如果你使用的是Swift 2.2)

问题#3

与dynamicType

比较时,您应该使用self

问题#4

你不能写section[i].isEnabled = false因为AnyObject没有会员isEnabled所以你应该做一个演员

问题#5

您正在访问数组之外​​的索引,因此

0...section.count

应该成为这个

0..<section.count

代码版本#1

现在你的代码看起来像这样

func disableSectionForm(formSection section: [AnyObject]) {
    for i in 0..<section.count {
        if section[i].dynamicType == UILabel.self {
            (section[i] as? UILabel)?.enabled = false
        } else if section[i].dynamicType == UITextField.self {
            (section[i] as? UITextField)?.enabled = false
        }
    }
}

代码版本#2

自:

  1. 您可以以更安全的方式迭代元素
  2. 您应该使用conditional cast代替dynamicType comparation
  3. 你可以写

      

    Swift 2.2

    func disableSectionForm(formSection section: [AnyObject]) {
        section.forEach {
            switch $0 {
            case let label as UILabel: label.enabled = false
            case let textField as UITextField: textField.enabled = false
            default: break
            }
        }
    }
    
      

    Swift 3.0(测试版6)

    func disableSectionForm(formSection section: [Any]) {
        section.forEach {
            switch $0 {
            case let label as UILabel: label.isEnabled = false
            case let textField as UITextField: textField.isEnabled = false
            default: break
            }
        }
    }
    

    代码版本#3

    让我们定义一个协议来表示具有enabled Bool属性的类。

      

    Swift 2.2

    protocol HasEnabledProperty:class {
        var enabled: Bool { get set }
    }
    

    让它符合UILabelUITextLabel

    extension UILabel: HasEnabledProperty { }
    extension UITextField: HasEnabledProperty { }
    

    最后......

    func disableSectionForm(formSection section: [AnyObject]) {
        section.flatMap { $0 as? HasEnabledProperty }.forEach { $0.enabled = false }
    }
    
      

    Swift 3.0(测试版6)

    protocol HasEnabledProperty:class {
        var isEnabled: Bool { get set }
    }
    
    extension UILabel: HasEnabledProperty { }
    extension UITextField: HasEnabledProperty { }
    
    func disableSectionForm(formSection section: [Any]) {
        section.flatMap { $0 as? HasEnabledProperty }.forEach { $0.isEnabled = false }
    }
    

答案 1 :(得分:0)

尝试检查是否阻止并使用选项

func disableSectionForm(formSection section: inout [AnyObject]) {
            for i in 0...section.count {
                if let label = section[i] as? UILabel {
                     label.isEnabled = false
                }
                if let textField = section[i] as? UITextFiled {
                     textField.isEnabled = false
                }
            }
 }