簡體   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