只有在调用了所有被调用的对象()调用turnOff()后才会关闭()

时间:2009-07-17 16:26:11

标签: flex actionscript-3

我想要有两个名为turnOn()和turnOff()的静态函数。

假设objectA调用turnOn(),则objectB调用turnOn()。然后objectA调用turnOff(),它不应该关闭,因为objectB也将它打开。

另外说objectA调用turnOn(),然后objectB调用turnOn()。然后objectB调用turnOff(),它不应该关闭,因为objectA还没有关闭它。

最后,如果objectA和objectB将其打开,它们会在关闭它时关闭。

我正在考虑跟踪调用了多少turnOn和TurnOff,并确保它匹配,但这并不真正准确,因为objectA可以调用turnOff()两次。

那么最好的处理方式是什么?

谢谢!

5 个答案:

答案 0 :(得分:1)

这听起来像引用计数

答案 1 :(得分:1)

最简单的方法就像你描述的那样:保持计数。如果您真的担心一个物体在没有打开它时将其关闭,您可以保留已打开它的所有物体的列表,并在它们关闭时从列表中删除它们。如果列表为空,您实际上可以将其关闭。

答案 2 :(得分:0)

编辑:示例代码在c#中 - 我没有意识到这不是一个c#问题。如果你的语言中有哈希表,字典,甚至二维数组(表),那么这个相同的基本模式仍然有效。

听起来你需要一种经过修改的引用计数 - 一个按对象计数的计数。这样的事情怎么样:


public class Switch
{
  private bool On;
  private Dictionary<object, int> ReferenceCounts = new ...
  public void TurnOn(object source)
  {
     int count = 0;
     if(ReferenceCounts.ContainsKey(source))
        count = ReferenceCounts[source];
     count++;
     ReferenceCounts[source] = count;
     On = true;
  }

  public void TurnOff(object source)
  {
    if(!ReferenceCounts.ContainsKey(source))
       return;

    int count = ReferenceCounts[source];
    count--;
    if(count == 0)
      ReferenceCounts.Remove(source)
    else
      ReferenceCounts[source] = count;

    if(ReferenceCounts.Count == 0)
      this.On = false;
  }
}

答案 3 :(得分:0)

我不是100%确定这是你正在寻找的东西,但我想你会想要一个静态数组来确定是什么。另外......公平警告,我没有测试这段代码。这是对我认为您可能要做的事情的粗略估计。

class Switchable {
    static var _onObjects:Array=new Array  ;
    static public  function turnOn(obj:Object):Void {
        if (_onObjects.indexOf(obj) == -1) {
            _onObjects.push(obj);
        }
    }
    static public  function turnOff(obj:Object):Void {
        var index=_onObjects.indexOf(obj);
        if (isOn() && index >= 0) {
            _onObjects=_onObjects.splice(index,1);
        }
    }
    static public  function isOn():Boolean {
        return _onObjects.length > 0;
    }
}
class ObjectA {
    public function Foo():Void {
        Switchable.turnOn(this);
    }
    public function Bar():Void {
        Switchable.turnOff(this);
    }
}
class ObjectB {
    public function Foo():Void {
        Switchable.turnOn(this);
    }
    public function Bar():Void {
        Switchable.turnOff(this);
    }
}
class Test {
    static public  function Main():Void {
        trace(Switchable.isOn());
        var a:ObjectA=new ObjectA  ;
        var b:ObjectB=new ObjectB  ;
        a.Foo();
        trace(Switchable.isOn());
        b.Foo();
        trace(Switchable.isOn());
        a.Bar();
        trace(Switchable.isOn());
        b.Bar();
        trace(Switchable.isOn());
    }
}

答案 4 :(得分:0)

解决方案分为两部分: - 如其他地方所建议的静态对象计数器 - 以及一个per-object isTurnedOn标志,可防止对象打开或关闭两次,这与伪代码的行相似:

...
private static in count = 0;
private boolean isTurnedOn = false;
...
public void TurnON() {
    if (!isTurnedOn) {
        isTurnedOn = true;
        ++count;
    }
}

public void TurnOff() {
    if (isTurnedOn) {
        isTunedOn = false;
        --count;
        if (count == 0) {
            // the conter reached 0, do soemthing
            // but do not forget to protect against concurretn access
    }
 }

请注意,此构造允许重复打开和关闭对象。如果你想阻止这种情况,你可能应该为isTurnedOn和isTurnedOff使用两个单独的布尔值。