繁体   English   中英

Swift / iOS:如何在AnyObject / Any或Pointers的函数中使用inout参数

[英]Swift/iOS: How to use inout parameters in functions with AnyObject/Any or Pointers

我正在尝试编写一个函数,它接受一个变量指针和一个描述符/键,并为变量设置一个新值。 理想情况下,指针应该是对象或基元,但我也可以使用单独的函数(或其他参数)。 在我的代码中,我也使用键从数据库中检索新值,但在下面的示例中,我使用虚拟值对其进行了简化,以便可以在操场中轻松使用:

import UIKit

func setValue(inout object: AnyObject, key: String) {
    switch key {
    case "String":
        object = "A String"
    case "UIColor":
        object = UIColor.whiteColor()
    case "Bool":
        object = true
    default:
        println("Unhandled key: \(key)")
    }
}

var string: String = "Default String"
var color: UIColor = UIColor.blackColor()
var bool: Bool = false

setValue(&string, "String")
setValue(&color, "UIColor")
setValue(&bool, "Bool")

我收到以下错误:

“无法使用类型'的参数列表调用'setValue'(inout String,key String)'”

我知道我在这里混合了对象和原始。 我也尝试将其分解并将它们分成两个函数,但即便失败:

func setValue(inout object: AnyObject, key: String) {
    switch key {
    case "UIColor":
        object = UIColor.whiteColor()
    default:
        println("Unhandled key: \(key)")
    }
}

var color: UIColor = UIColor.blackColor()
setValue(&color, "UIColor")

这也给出了同样的错误:

“无法使用类型'的参数列表调用'setValue'(inout UIColor,key String)'”

如果我将'AnyObject'更改为'UIColor'它可以工作,但函数的重点是,它需要任何变量类型或至少任何对象类型(我会使用“Any”为基元编写第二个函数然后添加另一个参数)

在Objective-C中我使用指针,将方法转移到Swift也不起作用,结果相同:

func setValue(object: UnsafeMutablePointer<AnyObject>, key: String) {
    switch key {
    case "String":
        object.memory = "A String"
    case "UIColor":
        object.memory = UIColor.whiteColor()
    case "Bool":
        object.memory = true
    default:
        println("Unhandled key: \(key)")
    }
}

有没有人知道我在这里缺少什么? 任何帮助深表感谢!

谢谢!

更好的是你可以创建如下的通用方法:

func setValue<T>(inout object:T, key: String) {
    switch key {
    case "String":
        object = ("A String" as? T)!
    case "UIColor":
        object = (UIColor.whiteColor() as? T)!
    case "Bool":
        object = (true as? T)!
    default:
        println("Unhandled key: \(key)")
    }
}

呼叫将是这样的:

setValue(&string, key: "String")
setValue(&color, key: "UIColor")
setValue(&bool, key: "Bool")

希望能帮助到你!

正确的方法是使用重载,让编译器在编译时选择适当的代码位,而不是在运行时关闭字符串:

func setValue(inout object: String) {
    object = "A String"
}

func setValue(inout object: UIColor) {
    object = UIColor.whiteColor()
}

func setValue(inout object: Bool) {
    object = true
}

func setValue(inout object: Any) {
    println("Unhandled key: \(key)")
}

当你有一个Any并希望向函数指示Any包含什么类型时,这种方法不起作用...但在这种情况下,你遇到问题的原因是编译器确实知道类型是什么,所以你可以利用这一点。

- 使用Any而不是AnyObject来覆盖值类型和结构。

- 在调用方法之前,您可能需要转换为Any。

例:

func swapAny( inout obj1: Any, inout obj2: Any )
{
    let temp = obj1
    obj1 = obj2
    obj2 = temp
}

使用:

var fooString: Any = "Foo"
var barString: Any = "Bar"

swapAny(&fooString, obj2: &barString)
println(fooString)//prints "Bar"

对inout的协议支持

当您将类转换为协议时,您最终会得到一个不可变引用,该引用无法在inout函数参数中使用。 所以你可以:

  1. 使用方法重载(即使您重构,也可能会复制您的代码并使其先天难以阅读)
  2. 不要使用inout(这是你应该做的)
  3. 或者你可以这样做:

-

protocol IPositional{
    func setPosition(position:CGPoint)
}
extension IPositional{
    var positional:IPositional {get{return self as IPositional}set{}}
}
class A:IPositional{
    var position:CGPoint = CGPoint()
    func setPosition(position:CGPoint){
        self.position = position
    }
}
func test(inout positional:IPositional){
    positional.setPosition(CGPointMake(10,10))
}
var a = A()
test(&a.positional)
a.position//output: (10.0, 10.0)

结论:
这样做的好处是:你现在可以为实现IPositional的所有类都有一个“inout方法”但是我建议选择2。(不使用inout)

对象的类型应该与参数的类型匹配,包括AnyObject

func setValue(inout object: AnyObject, key: String) {
    switch key {
    case "String":
        object = "A String"
    case "UIColor":
        object = UIColor.whiteColor()
    case "Bool":
        object = true
    default:
        print("Unhandled key: \(key)")
    }
}

var string: AnyObject = "Default String"
var color: AnyObject = UIColor.blackColor()
var bool: AnyObject = false

setValue(&string, key: "String")
setValue(&color, key: "UIColor")
setValue(&bool, key: "Bool")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM