我习惯了更多事件驱动的环境,但我现在正在使用的副本将所有内容都作为函数回调。当我问起这个开发人员说这是因为冒泡时回调更快,但冒泡的属性总是可以设置为假...
所以我遇到了试图找出正在引用哪个回调函数的问题。
例如:
public class A {
public function A(){}
public function func_1():Number{ return 1; }
public function func_2():Number{ return 2; }
public function doSomething:Function{
if( Math.random > 0.5 ) return func_1; else return func_2;
}
}
然后我可以在B类中运行代码:
public class B{
public var a:A = new A();
private var action:Function;
public function B(){ action = a.doSomenthing(); }
}
所以当我在BI内部设置一个断点时,获取动作=功能(@ 34567)这实际上是完全无用的......我意识到我可以在func_1和func_2中设置一个断点,但我只是将它用作一般的例子,在代码中散布着函数回调...是否有办法通过内存地址获取函数的名称?感谢
我想我看到你对堆栈跟踪的看法。但是你必须在代码中逐步完成该功能。在下面的这个例子中,我必须在callback()上设置一个断点;并跳过它以查看堆栈跟踪更新。问题是我想在调用之前知道回调。有时它们在其他地方被召唤。没有其他方法可以获得回调?
public var callbacks:Array = [];
public function loadURL( url:String, callback:Function ){
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
callbacks.push( callback );
var request:URLRequest = new URLRequest(url);
loader.load(request);
}
public function completeHandler( event:Event ):void
{
for( var i:int = 0; i < callbacks.length; i ++ ){
var callback:Function = callbacks[i];
callback();
}
}
答案 0 :(得分:2)
这是非常难以置信的代码,但是为了这个例子,您可以使用调试器中的调用堆栈:
您的示例代码存在许多问题,但此捕获是基于对您的实现的轻微调整:
package
{
import flash.display.Sprite;
public class MultiCallback extends Sprite
{
public function MultiCallback()
{
super();
var b:B = new B();
b.action()();
}
}
}
internal class A
{
public function A()
{
}
public function func_1():Number
{
return 1;
}
public function func_2():Number
{
return 2;
}
public function doSomething():Function
{
if (Math.random() > 0.5)
return func_1;
else
return func_2;
}
}
internal class B
{
public var a:A = new A();
public var action:Function;
public function B()
{
action = a.doSomething;
}
}
答案 1 :(得分:2)
你可以在try ... catch中抛出一个错误,这样你就可以在不杀死应用程序的情况下检查堆栈。这个解决方案让我感到畏缩,但同时又很狡猾。最初由Ralf Bokelberk撰写,但由于他的博客目前不起作用I'll link to here instead,这是我发现它的地方。
以下是后代代码中的技巧:
var stackTrace:String;
try { throw new Error(); }
catch ( e: Error ) { stackTrace = e.getStackTrace(); }
var lines:Array = stackTrace.split('\n');
var isDebug Boolean = (lines[int(1)] as String).indexOf('[') != int(-1);
var path:String;
var line:int = -1;
if (isDebug) {
var regex:RegExp = /at\x20(.+?)\[(.+?)\]/i;
var matches:Array = regex.exec(lines[int(2)]);
path = matches[int(1)];
//file:line = matches[2]
line = matches[int(2)].split(':')[int(2)];//windows == 2 because of drive:\
} else {
path = (lines[int(2)] as String).substring(4);
}
答案 2 :(得分:1)
男子我在同一条船上。这个代码库是巨大的,并以相同的方式完成。在我的案例中,“洒水”将是轻描淡写。如果函数对象没有函数名称处理程序,那么您就是SOL。我理解代码的方法之一是使用UML来表示这些不同的类,并使用关联运算符来显示这是在调用某些东西。当回调回调另一个回调时,它很容易迷失。你制作的UML图就像面包屑,试图让自己脱离兔子洞。过了一会儿,你就习惯了。我会采用这种编程方式吗?不,他们只是让下一个人难以维持。我使用Violet UML来跟踪我在回调中的旅程。