I use mx.utils.Delegate.create constantly, however in looking at the source code, there are some memory inefficiencies. In the create method, there is a function literal (the var f). By creating this function literal, the create method is actually prolonging the scope of it’s arguments and it’s local variables in the scope of f for the lifetime of f. So what does all this mean? Well, it means that in the scope of f you have create’s argument’s obj and func still available. Yet, f reference’s these values by creating local variables from static properties attached to the function itself, instead of accessing them directly.
Therefore, the assignments of the properties to f:
f.target = obj;
f.func = func;
and the local variables of f
var target = arguments.callee.target; var func = arguments.callee.func;
are like making multiple assignments of the same variable
var target1:Object = new Object(); var target2:Object = target1; var target3:Object = target2;
To be more efficient, the create method could simply be rewritten to use the create arguments in the scope of f:
static function create(o:Object, f:Function):Function { return function() { return f.apply(o, arguments); }; }
This information is important to note only if you have use the mx.utils.Delegate.create heavily.
[UPDATE]
Since I use my own class instead of the mx.utils.Delegate, I hadn’t modified it directly. In doing so, I found out there was a a confusion on the which scope func was in, since it was defined as a private instance var as well. This definition creates conflict with the argument func of the create method. Therefore, the vars need to be named different. This is good practice anyways and it eliminates this conflict. I changed the create method definition above to reflect this.

Subscribe to RSS
#1 by Ash on January 7, 2005 - 7:31 am
Interesting observation.. but I think the original version needs to keep a copy of the original target and function.
The function you return in your version no longer has ‘func’ or ‘obj’ in it’s scope when it is called (which is sometime later).
I tried replacing it in Delegate.as, and my Delegate callbacks no longer work.
#2 by Kenny Bunch on January 7, 2005 - 7:37 am
Ash,
It does keep a copy of obj and func in it’s scope. That is the point of the post. As long as the anonymous function that is returned exists in memory those arguments obj and func exist in it’s scope and are held in memory as well. Can you post an example of how you are using it?
#3 by Ash on January 7, 2005 - 7:42 am
I’ve always used the Delegate class like this:
listeners = new Object();
listeners.onLoadComplete = Delegate.create(this, onLoadComplete);
listeners.onLoadStart = Delegate.create(this, onLoadStart);
loader = new MovieClipLoader();
loader.addListener(listeners);
And using the EventDispatcher class like this:
_comms.addEventListener(“message”, Delegate.create(this, onMessage));
#4 by Kenny Bunch on January 7, 2005 - 7:53 am
Ash,
Corrected the issue, it was a conflict. Check my revised post above.
#5 by Ash on January 7, 2005 - 8:04 am
Now it works
Thanks!
#6 by Keith Peters on January 7, 2005 - 11:48 am
I understand the issue, but have you ever seen this to cause an actual problem? I don’t see how it could ever become a real live issue in a program. It’s not even like it’s going to cause a progressive memory leak, it just wastes a few bytes. By the time you created enough delegates for the waste to become an issue, the program would have already crashed from the weight of the delegates alone. I understand that from a purist viewpoint it is bad, but pragmatically, it’s not something that anyone should ever have to worry about. If someone can create a program that demonstrates this causing a real problem, I’d love to see it.
#7 by Kenny Bunch on January 7, 2005 - 12:22 pm
Ketih,
You are correct, this will probably never be a large issue in most applications. It won’t cause a memory leak, just memory waste. However, if you program games or anything that is system intensive, everything matters down to the smallest issues. From that standpoint, a purist mindset is important, because everything must be efficient. I wouldn’t want people running for their lives because they think all their apps are going to be slow because of this. That is not gonna happen, I just like to pay attention to all the details since they can add up. Good point though.