|
AS3 中的反射 AS3 中的反射 3
我们再试一下获取实例的信息 :
var sprite1:Sprite = new Sprite(); var instanceInfo:XML = describeType(sprite1);
返回 :
代码
<type name="flash.display::Sprite" base="flash.display::DisplayObjectContainer" isDynamic="false" isFinal="false" isStatic="false"> <extendsClass type="flash.display::DisplayObjectContainer"/> <extendsClass type="flash.display::InteractiveObject"/> <extendsClass type="flash.display::DisplayObject"/> <extendsClass type="flash.events::EventDispatcher"/> <extendsClass type="Object"/> <implementsInterface type="flash.display::IBitmapDrawable"/> <implementsInterface type="flash.events::IEventDispatcher"/> <accessor name="hitArea" access="readwrite" type="flash.display::Sprite" declaredBy="flash.display::Sprite"/> <method name="startDrag" declaredBy="flash.display::Sprite" returnType="void"> <parameter index="1" type="Boolean" optional="true"/> <parameter index="2" type="flash.geom::Rectangle" optional="true"/> </method> <accessor name="buttonMode" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/> <accessor name="graphics" access="readonly" type="flash.display::Graphics" declaredBy="flash.display::Sprite"/> <accessor name="soundTransform" access="readwrite" type="flash.media::SoundTransform" declaredBy="flash.display::Sprite"/> <method name="stopDrag" declaredBy="flash.display::Sprite" returnType="void"/> <accessor name="dropTarget" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::Sprite"/> <accessor name="useHandCursor" access="readwrite" type="Boolean" declaredBy="flash.display::Sprite"/> <method name="getChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="int" optional="false"/> </method> <method name="addChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="swapChildren" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="flash.display::DisplayObject" optional="false"/> </method> <method name="getChildByName" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="String" optional="false"/> </method> <method name="getObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Array"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="textSnapshot" access="readonly" type="flash.text::TextSnapshot" declaredBy="flash.display::DisplayObjectContainer"/> <method name="removeChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="int" optional="false"/> </method> <method name="getChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="int"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="areInaccessibleObjectsUnderPoint" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="mouseChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/> <method name="removeChild" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="setChildIndex" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <method name="contains" declaredBy="flash.display::DisplayObjectContainer" returnType="Boolean"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <method name="addChildAt" declaredBy="flash.display::DisplayObjectContainer" returnType="flash.display::DisplayObject"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <accessor name="numChildren" access="readonly" type="int" declaredBy="flash.display::DisplayObjectContainer"/> <method name="swapChildrenAt" declaredBy="flash.display::DisplayObjectContainer" returnType="void"> <parameter index="1" type="int" optional="false"/> <parameter index="2" type="int" optional="false"/> </method> <accessor name="tabChildren" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObjectContainer"/> <accessor name="tabEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="doubleClickEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="contextMenu" access="readwrite" type="flash.ui::ContextMenu" declaredBy="flash.display::InteractiveObject"/> <accessor name="accessibilityImplementation" access="readwrite" type="flash.accessibility::AccessibilityImplementation" declaredBy="flash.display::InteractiveObject"> <metadata name="Inspectable"> <arg key="environment" value="none"/> </metadata> </accessor> <accessor name="mouseEnabled" access="readwrite" type="Boolean" declaredBy="flash.display::InteractiveObject"/> <accessor name="focusRect" access="readwrite" type="Object" declaredBy="flash.display::InteractiveObject"/> <accessor name="tabIndex" access="readwrite" type="int" declaredBy="flash.display::InteractiveObject"/> <accessor name="mask" access="readwrite" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/> <accessor name="scaleX" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="scaleY" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="getRect" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="mouseY" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="alpha" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="x" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="name" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/> <accessor name="y" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="root" access="readonly" type="flash.display::DisplayObject" declaredBy="flash.display::DisplayObject"/> <accessor name="width" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <accessor name="stage" access="readonly" type="flash.display::Stage" declaredBy="flash.display::DisplayObject"/> <accessor name="loaderInfo" access="readonly" type="flash.display::LoaderInfo" declaredBy="flash.display::DisplayObject"/> <accessor name="transform" access="readwrite" type="flash.geom::Transform" declaredBy="flash.display::DisplayObject"/> <accessor name="height" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="localToGlobal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <accessor name="filters" access="readwrite" type="Array" declaredBy="flash.display::DisplayObject"/> <accessor name="blendMode" access="readwrite" type="String" declaredBy="flash.display::DisplayObject"/> <accessor name="rotation" access="readwrite" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="hitTestObject" declaredBy="flash.display::DisplayObject" returnType="Boolean"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="scale9Grid" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/> <accessor name="accessibilityProperties" access="readwrite" type="flash.accessibility::AccessibilityProperties" declaredBy="flash.display::DisplayObject"/> <accessor name="scrollRect" access="readwrite" type="flash.geom::Rectangle" declaredBy="flash.display::DisplayObject"/> <accessor name="cacheAsBitmap" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/> <method name="globalToLocal" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Point"> <parameter index="1" type="flash.geom::Point" optional="false"/> </method> <method name="getBounds" declaredBy="flash.display::DisplayObject" returnType="flash.geom::Rectangle"> <parameter index="1" type="flash.display::DisplayObject" optional="false"/> </method> <accessor name="opaqueBackground" access="readwrite" type="Object" declaredBy="flash.display::DisplayObject"/> <accessor name="parent" access="readonly" type="flash.display::DisplayObjectContainer" declaredBy="flash.display::DisplayObject"/> <method name="hitTestPoint" declaredBy="flash.display::DisplayObject" returnType="Boolean"> <parameter index="1" type="Number" optional="false"/> <parameter index="2" type="Number" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> </method> <accessor name="visible" access="readwrite" type="Boolean" declaredBy="flash.display::DisplayObject"/> <accessor name="mouseX" access="readonly" type="Number" declaredBy="flash.display::DisplayObject"/> <method name="willTrigger" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> <method name="removeEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> </method> <method name="toString" declaredBy="flash.events::EventDispatcher" returnType="String"/> <method name="addEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> <parameter index="4" type="int" optional="true"/> <parameter index="5" type="Boolean" optional="true"/> </method> <method name="dispatchEvent" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="flash.events::Event" optional="false"/> </method> <method name="hasEventListener" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> </type>
所有的标签与之前 factory 标签中的内容是一样的
现在我们使用 describeType 来遍历之前 Dummy 类中的元素
实例化:
var dummy:Dummy = new Dummy(); 获取实例信息:
var instanceInfo:XML = describeType(dummy); 把所有的属性取出来, 包括访问器和变量, 并且访问器不可为只写:
var properties:XMLList = instanceInfo..accessor.(@access != "writeonly") + instanceInfo..variable; 此时 properties 里就有所有的属性名了. 最后我们遍历这个 XMLList
for each (var propertyInfo:XML in properties) { // 取出属性名 var propertyName:String = propertyInfo.@name; // 根据属性名来访问 trace(dummy[propertyName]); }
这样 dummy 就被 "遍历" 出了~
完整代码:
代码
var dummy:Dummy = new Dummy(); var instanceInfo:XML = describeType(dummy); var properties:XMLList = instanceInfo..accessor.(@access != "writeonly") + instanceInfo..variable; for each (var propertyInfo:XML in properties) { var propertyName:String = propertyInfo.@name; trace(dummy[propertyName]); }
这样我们可以专门写一个类, 负责获取类信息, 详细见类中注释 TypeDescriptor.as, 负责获取信息
代码
package { import flash.utils.describeType; import flash.utils.getQualifiedClassName; import flash.utils.getDefinitionByName; /** * 使用 flash.utils.describeType 获取类详细信息并缓存 * @author kakera * */ public class TypeDescriptor { /** * 缓存已经反射过了的对象 */ private static var typeCache:Object = new Object(); /** * 获取类信息 * @param target 要获取的目标对象 * @return TypeDescriptorEntry 实例 * */ public static function describeType (target:*):TypeDescription { var className:String = getQualifiedClassName(target); /** * 检查缓存中是否已经有目标对象项, 如果有就返回缓存中的内容 */ if (className in typeCache) return typeCache[className]; /** * 暂存属性列表 */ var propertyNames:Array = []; /** * 获取类信息, 如果传入的是实例则获取实例类型的类信息 */ var typeInfo:XML = flash.utils.describeType(target is Class ? target : getDefinitionByName(className) as Class); /** * 获取类中所有的属性和访问器 */ var properties:XMLList = typeInfo.factory..accessor.(@access != "writeonly") + typeInfo..variable; /** * 遍历并存放到 propertyNames 中 */ for each (var propertyInfo:XML in properties) propertyNames.push(propertyInfo.@name); /** * 创建 TypeDescriptorEntry 的实例并把 propertyNames 等属性丢进去 */ var entry:TypeDescription = new TypeDescription(); entry.name = className; entry.properties = propertyNames; entry.typeInfo = typeInfo; /** * 缓存到 typeCache 中以便下次从缓存中读取 */ typeCache[className] = entry; return entry; } /** * 静态类无须实例化 * @return * */ public function TypeDescriptor () } }
TypeDescription.as, 负责保存信息
代码
package { public class TypeDescription { /** * 类的属性列表, 包括访问器 (accessor) 和变量 (variable) */ public var properties:Array; /* of String */ /** * 类名 */ public var name:String;
/** * 由 flash.utils.describeType() 获取的原始 XML 数据 */ public var typeInfo:XML; public function TypeDescription () } }
|