如何传递对布尔值的引用而不是其值?

时间:2016-11-22 14:57:35

标签: swift reference boolean

我想将布尔值用作状态存储。

为了做到这一点,我需要能够从项目的不同位置改变他们的状态。

要做到这一点,我需要一个地方来存储它们,以及一种传递对它们的引用的方法。

我已经尝试将它们存储为static variables in a GameManager,但是只传递对这些的引用似乎传递了false的值,而不是引用。

如何实现具有可通过布尔引用的目标我可以从项目的任何部分更改它的状态?

UPDATE:

这可能不是最好的方法,但这实现了我可以在游戏世界中使用一堆状态布尔值的目标:

class GameManager {

    static let sharedInstance = GameManager()

    var previewAudioIsON: Bool = false
    var previewVisuaIsOn: Bool  = false
    var timerDisplayIsOn: Bool  = false
    var quickStartIsOn: Bool  = false

    func touchedPreviewAudioButton() -> Bool {
        if previewAudioIsON { previewAudioIsON = false}
        else { previewAudioIsON = true }
     return previewAudioIsON
    }

    func touchedPreviewVisualButton() -> Bool {
        if previewVisuaIsOn { previewVisuaIsOn = false }
        else { previewVisuaIsOn = true }
     return previewVisuaIsOn
    }

    func touchedTimeDisplayButton() -> Bool {
        if timerDisplayIsOn { timerDisplayIsOn = false }
        else { timerDisplayIsOn = true }
     return timerDisplayIsOn
    }

    func touchedQuickStartButton() -> Bool {
        if quickStartIsOn { quickStartIsOn = false }
        else { quickStartIsOn = true }
     return quickStartIsOn
    }
}

2 个答案:

答案 0 :(得分:1)

前几天我给了你一些错误的信息(我有一个脑屁),需要为此道歉。我在测试中忽略了一些东西......

如果您不想按照我的建议制作RefBool个实例,则需要以下内容(需要更多的工作,不推荐):

/// Mutates a boolean:
func toggle(_ boolean: inout Bool) -> Bool {
  boolean ? (boolean = false) : (boolean = true)
  return boolean
}

/// Static state manager for Booleans
struct IsOn {

    private static var
    _previewAudio  = false,
    _previewVisual = false,
    _timerDisplal  = false,
    _quickStart    = false

    enum State { case toggle, get }

   static func previewAudio(_ toggleVal: State = .get) -> Bool {
    if toggleVal == .toggle { toggle(&_previewAudio) }; return _previewAudio
  }

   // ... others
}

测试:

let referenceToPA = IsOn.previewAudio

print ( IsOn.previewAudio() ) // False (default pram works)
print ( referenceToPA(.get) ) // False (can't use default pram)

referenceToPA(.toggle) 

print ( IsOn.previewAudio() ) // True
print ( referenceToPA(.get) ) // True

IsOn.previewAudio(.toggle)

print ( IsOn.previewAudio() ) // False
print ( referenceToPA(.get) ) // False

但老实说,从我的另一个答案中做RefBool会更容易,那么你就不需要枚举或函数了:

/// Holds a boolean in .val:
final class RefBool { var val: Bool; init(_ boolean: Bool) { val = boolean } }

/// Static state manager for Booleans
struct IsOn {
    static var
      previewAudio  = RefBool(false),
      previewVisual = RefBool(false),
      timerDisplal  = RefBool(false),
      quickStart    = RefBool(false)
}

便利功能(不必要):

/// Mutates a boolean:
func toggle(_ boolean: inout Bool) -> Bool {
  boolean ? (boolean = false) : (boolean = true)
  return boolean
}

/// Mutates .val:
func toggle(_ refBool: RefBool) -> Bool {
    refBool.val ? (refBool.val = false) : (refBool.val = true)
    return refBool.val
}

Testing2:

let refToPA = IsOn.previewAudio

refToPA.val = true

print(refToPA.val) // true
print(IsOn.previewAudio.val) // true

toggle(&refToPA.val)

print(refToPA.val) // false
print(IsOn.previewAudio.val) // false

toggle(refToPA) // Using our fancy second toggle

print(refToPA.val) // true
print(IsOn.previewAudio.val) // true

答案 1 :(得分:0)

尝试类似的事情:

完整示例

import UIKit

enum ButtonType {
    case PreviewAudio;
    case PreviewVisua;
    case TimerDisplay;
    case QuickStart;
}

class SwitchProperty {

    var type: ButtonType
    var value: Bool

    init (type: ButtonType) {
        self.type = type
        self.value = false
    }

    var description: String {
        var result = "type = \(type)\n"
        result += "value = \(value)"
        return result
    }

    func switchValue() {
        value.invertValue()
    }
}

class GameManager {

    static var previewAudioIsON = SwitchProperty(type: .PreviewAudio)
    static var previewVisuaIsOn = SwitchProperty(type: .PreviewVisua)
    static var timerDisplayIsOn = SwitchProperty(type: .TimerDisplay)
    static var quickStartIsOn = SwitchProperty(type: .QuickStart)

}

class Button: UIButton {
    var switchValue: SwitchProperty
    init (type: ButtonType, frame: CGRect) {
        switch type {
        case .PreviewAudio:
            switchValue = GameManager.previewAudioIsON
        case .PreviewVisua:
            switchValue = GameManager.previewVisuaIsOn
        case .TimerDisplay:
            switchValue = GameManager.timerDisplayIsOn
        case .QuickStart:
            switchValue = GameManager.quickStartIsOn
        }
        super.init(frame: frame)
        addTarget(self, action: #selector(Button.buttonTouched), for: .touchUpInside)
    }

    func buttonTouched() {
        switchValue.switchValue()
        print(switchValue.description)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension Bool {
    mutating func invertValue() {
        self = !self
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        addButton(type: .PreviewVisua, frame: CGRect(x: 40, y: 40, width: 200, height: 40));
        addButton(type: .PreviewAudio, frame: CGRect(x: 40, y: 100, width: 200, height: 40));
    }

    func addButton(type: ButtonType, frame: CGRect) {
        let button = Button(type: type, frame: frame);
        button.setTitleColor(UIColor.blue, for: .normal)
        button.setTitle("\(type)", for: .normal)
        view.addSubview(button)
    }
}

属性来自另一个代码

// change value
GameManager.previewAudioIsON.value = false
// check type
if (GameManager.previewAudioIsON.type == .PreviewAudio) {
    print("previewAudioIsON")
}

结果

enter image description here