关于Actionscript 3中Dictionary类的几个问题:
检查未使用密钥的最佳方法是什么?我现在正在做dictionary[key] == undefined
。这是最快最干净的方式吗?
我是否需要遍历delete dictionary[key]
或者我可以让字典超出范围吗?
是否有更好的解决方案将消息侦听器映射到广播类?我做这样的事情:
addListener(function : Function, messageType : Type)
{
if(dictionary[messageType] == undefined)
dictionary[messageType] = new Vector<Function>();
dictionary[messageType].push(function);
}
broadcast(message : Message, messageType : Type)
{
if(dictionary[messageType] != undefined)
{
for each(var function : Function in dictionary[messageType])
function(message);
}
}
我现在只输出,所以它可能不是100%准确。使用带有类似字典的路由系统是个好主意吗?
答案 0 :(得分:7)
1 - 您有两个有效选项:与undefined
比较或与null
比较。区别是这样的:
undefined
:根本不存在值null
:存在一个值,但包含null 所以,你选择适合你的情况。见例子。
import flash.utils.Dictionary;
var test:Dictionary = new Dictionary();
trace(test[1] == null); // true, because null is internally converted to undefined
trace(test[1] === null); // false, because of strictly typed comparison
trace(test[1] == undefined); // true
trace(test[1] === undefined); // true
2 - 当我在那里有引用时,我总是通过字典循环来清理它们(而不仅仅是数字或字符串之类的ptimitive类型)。好吧,它应该没有必要,但这样我帮助垃圾收集器一点点,这通常是一个好主意。
3 - 这个让我感到困惑。你为什么需要这样播放?它看起来很像我们之前在AS1-2中使用AsBroadcaster类的那些,非本地为我们提供了广播功能。 AS3有一个本机事件调度系统,您可以根据需要进行升级(例如,如果您需要维护每种事件类型的侦听器列表)。
这些链接可能很有用:
答案 1 :(得分:2)
你也可以写if (!dictionary[key]) ...
您可以使字典对象无效,而不是循环删除所有键:dictionary = null;
我写了一个广播班,如果你愿意的话,绝对欢迎你使用它!它非常适用于非显示对象之间的全局通信。但是,如果您想允许显示对象之间的全局通信,您可以通过舞台添加和发送自定义事件 - 当然,假设它们已添加到舞台中。
Broadcast.as
package com.mattie.events.broadcaster
{
//Class
public class Broadcast
{
//Variables
public var name:String;
public var data:Object;
//Constructor
public function Broadcast(name:String, data:Object)
{
this.name = name;
this.data = data;
}
}
}
Broadcaster.as
package com.mattie.events.broadcaster
{
//Imports
import flash.utils.Dictionary;
//Class
public final class Broadcaster
{
//Properties
private static var singleton:Broadcaster;
private var publicationsProperty:Dictionary;
private var subscriptionsProperty:Array;
//Constructor
public function Broadcaster()
{
if (singleton)
throw new Error("Broadcaster is a singleton that cannot be publically instantiated and is only accessible thru the \"broadcaster\" public property.");
publicationsProperty = new Dictionary(true);
subscriptionsProperty = new Array();
}
//Publish Data
public function publish(name:String, data:Object = null):void
{
publicationsProperty[name] = data;
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name)
{
var handler:Function = subscriptionsProperty[i].handler;
handler(new Broadcast(name, data));
}
}
//Subscribe Handler
public function subscribe(name:String, handler:Function):void
{
if (publicationsProperty[name])
handler(new Broadcast(name, publicationsProperty[name]));
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name && subscriptionsProperty[i].handler == handler)
return;
subscriptionsProperty.push({name: name, handler: handler});
}
//Unpublish Data
public function unpublish(name:String):void
{
delete publicationsProperty[name];
}
//Unsubscribe Handler
public function unsubscribe(name:String, handler:Function):void
{
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name && subscriptionsProperty[i].handler == handler)
{
subscriptionsProperty.splice(i, 1);
return;
}
}
//Publications Getter
public function get publications():Dictionary
{
return publicationsProperty;
}
//Subscriptions Getter
public function get subscriptions():Array
{
return subscriptionsProperty;
}
//Singleton Getter
public static function get broadcaster():Broadcaster
{
if (!singleton)
singleton = new Broadcaster();
return singleton;
}
}
}