【问题标题】:Cannot pass immutable value of type 'NSObject' as inout argument无法将“NSObject”类型的不可变值作为 inout 参数传递
【发布时间】:2016-11-11 11:40:42
【问题描述】:

这应该可行,但我不知道为什么不可行。代码一目了然。

class Themer {

   class func applyTheme(_ object: inout NSObject) {
      //do theming
   }
}

我将主题应用于按钮,如下所示:

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!
    override func viewDidLoad() {

        super.viewDidLoad()
        Themer.applyTheme(&button)
    }

按钮对象是一个变量,但编译器会抛出错误。

【问题讨论】:

  • 使用UIView 而不是NSObject
  • 想想如果applyTheme(_:)object 设置为NSNumber 实例(继承自NSObject,因此是合法的)会发生什么;)
  • 您不能将 X 类型的变量传递给 X 的某个父级的 inout。

标签: ios swift swift3 immutability inout


【解决方案1】:

由于按钮是一个对象,所以这个语法

Themer.applyTheme(&button)

表示您要更改对该对象的引用。但这不是你想要的。你想改变引用的对象,所以你只需要写

Themer.applyTheme(button)

最后你也不需要inout注解

class Themer {
    class func applyTheme(_ object: AnyObject) {
        //do theming
    }
}

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        Themer.applyTheme(self.button)

    }
}

但是……

但是,您的applyTheme 方法应该做什么?它收到AnyObject 然后呢?你可以让它更具体一点,并使用 UIView 作为参数

class Themer {
    class func applyTheme(view: UIView) {
        //do theming
    }
}

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        Themer.applyTheme(view: button)
    }
}

现在您有机会在 Themer.applyTheme 中编写有意义的代码。

【讨论】:

  • 请注意,您可以inout 与引用类型一起使用——它允许函数更改传递给它的变量的引用。虽然你是对的,这可能不是 OP 想要的。
  • @Hamish 你说得对,我会更正我的说法。谢谢!
  • 当我发现没有像我这样的问题时,我知道我做错了,尽管这应该很常见。谢谢
【解决方案2】:

inout 适用于您要更改引用的情况,即将一个对象替换为另一个对象。这对 IBOutlet 来说是一件非常、非常、非常糟糕的事情。该按钮用于视图,连接了很多东西,如果你改变变量,所有的地狱都会崩溃。

除此之外,听听 appzYourLife。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多