Actionscript 3 - 脚本库
我正在尝试手动加载 swc 构建生成的 swf。由于我的特定环境,我们需要将类定义分离到 swc 中(在有意义的情况下),以从输出 swf 中删除冗余代码。
简而言之,我在使用 compc
构建的 swf 中定义了一个类 (LibA
)。我将其编译为 swc 和目录格式,以便我可以轻松地从目录中提取library.swf 以在运行时加载(外部链接),并使用 swc 从使用 Flash CS5 或 mxmlc 构建的任何 swf 进行编译。
LibA.as:
package
{
public class LibA
{
public function LibA()
{
trace("*** LibA()");
}
}
}
Main.as:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
public class Main extends Sprite
{
private var self:Main;
private var context:LoaderContext;
public function Main()
{
var l:Loader = new Loader();
self = this;
l.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event) {
self.addChild(l.content);
var liba:LibA = new LibA();
});
l.load(new URLRequest("./libs/build/liba.swf"));
}
}
}
构建了 swc/目录 swc
我使用compc -output libs/build/liba.swc -include-sources libs/LibA .as -debug=true
并且我在构建 Main
时在 Flash CS5 的 AS3 设置中设置了适当的链接(直接链接到舞台的类)。
一切都可以毫无问题地发布。
但是,在运行时我得到 VerifyError: Error #1014: Class LibA Could not be find.
我在这里缺少什么?我希望能够从我的 Main.swf
加载和使用在 liba.swf
中定义的类。
完整跟踪转储:
verify Function/<anonymous>()
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
0:getlex 4
stack: Main?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
2:getlex 7
stack: Main? flash.display::Loader?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
4:getproperty content
stack: Main? flash.display::DisplayObject?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
6:callpropvoid addChild 1
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
9:findpropstrict LibA
stack: Object
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
11:constructprop 10 0
stack: *
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
14:coerce LibA
VerifyError: Error #1014: Class LibA could not be found.
I'm attempting to load the resulting swf of a swc build manually. Due to my particular environment, we have a need to segregate class definitions into swcs (where it makes sense) to remove redundant code from output swfs.
In a nutshell, I'm defining a class (LibA
) in a swf that I'm building with compc
. I'm compiling it both into swc and directory formats so I can easily extract library.swf from the directory to load at runtime (external linkage) and use the swc to compile out from any swf's built either with Flash CS5 or mxmlc
.
LibA.as:
package
{
public class LibA
{
public function LibA()
{
trace("*** LibA()");
}
}
}
Main.as:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
public class Main extends Sprite
{
private var self:Main;
private var context:LoaderContext;
public function Main()
{
var l:Loader = new Loader();
self = this;
l.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event) {
self.addChild(l.content);
var liba:LibA = new LibA();
});
l.load(new URLRequest("./libs/build/liba.swf"));
}
}
}
I build the swc/directory swc with
compc -output libs/build/liba.swc -include-sources libs/LibA.as -debug=true
and I set the appropriate linkage in AS3 settings in Flash CS5 when building Main
(class linked directly to the stage).
Everything publishes without an issue.
However, at runtime I get VerifyError: Error #1014: Class LibA could not be found.
What am I missing here? I want to be able to load and use classes defined within liba.swf
from my Main.swf
.
Full trace dump:
verify Function/<anonymous>()
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
0:getlex 4
stack: Main?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
2:getlex 7
stack: Main? flash.display::Loader?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
4:getproperty content
stack: Main? flash.display::DisplayObject?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
6:callpropvoid addChild 1
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
9:findpropstrict LibA
stack: Object
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
11:constructprop 10 0
stack: *
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
14:coerce LibA
VerifyError: Error #1014: Class LibA could not be found.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想从 SWF 加载类,您需要执行类似的操作(在您的事件处理程序中):
创建一个新的
c
应该为您提供您的LibA
对象。您需要完整的类定义作为名称。如果我明白你想要做什么,我很确定你可以将 SWC 设置为嵌入外部库 - 也就是说,你可以获得代码完成,但不包含任何类,并且会搜索 SWC在运行时。
编辑
刚刚尝试了类似您正在做的事情。在上面的示例中,当您创建
c
时,如果您跟踪它,它将跟踪LibA
。但是,如果您明确引用它,您将收到您所描述的错误。我认为这是因为 Flash 与 LibA 的 2 个定义(被引用的定义和您正在加载的定义)混淆了,它们位于 2 个不同的应用程序域中。解决方法是按照 @turbosqel 的描述,使用 LoaderContext 对象加载它:
这对我有用,我现在可以显式引用 LibA 类。
If you want to load classes from a SWF, you'll need to do something like (in your event handler):
Creating a new
c
should give you yourLibA
object. You'll need the full class definition as a name.If I understand what you're trying to do though, I'm pretty sure you can set the SWC to embed an an external library - that is you get code completion, but none of the classes are included, and the SWC is searched for at runtime.
EDIT
Just tried something like what you're doing. In my example above, when you create
c
, if you trace it out, it'll traceLibA
. However, if you explicitly reference it, you'll get the error that you describe. I think this is because Flash is getting confused with essentially 2 definitions ofLibA
- the one that was referenced and the one you're loading - they're in 2 different application domains.The fix is as @turbosqel describes it, load it in with a
LoaderContext
object:This works for me, I can now explicitly reference the
LibA
class.在加载 SWF 之前,liba 并不存在,因为您没有将其导入到 main 中。
这意味着在编译时它不存在
将
var liba:LibA = new LibA();
移动到加载的 swf 根上的函数调用中,并在加载e.currentTarget.someFunc 后调用该函数
liba does not exist until your SWF is loaded because you are not importing it into main.
Which means at compile time it is not there
Move
var liba:LibA = new LibA();
into a function call on the loaded swf root and call the function after loade.currentTarget.someFunc