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

15 浏览
0 Comments

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

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

为了实现这一点,我需要能够从项目中的不同位置更改它们的状态。

为此,我需要一个地方来存储它们,以及一种传递引用的方法。

我尝试将它们存储为GameManager中的静态变量,但是传递这些变量的引用似乎只传递了true或false的值,而不是引用。

我如何实现拥有可传递的布尔值引用的目标,可以在项目的任何部分更改它的状态?

更新:

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

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
    }
}

admin 更改状态以发布 2023年5月20日
0
0 Comments

试试这样做:

完整示例

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

0
0 Comments

我前几天提供了部分错误的信息(我当时脑子有点发懵),需要为此道歉。我在测试中忽视了一些内容...

如果你不想像我建议的那样创建 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
}

测试2:

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

0