Yes, we need to allow [Bindable] on interfaces, even if it is an
inefficient way to write your code.

More details on why it is inefficient:

You can’t have a “var” in an interface, only functions/getter/setters.
[Bindable] was really meant to switch a var into a getter/setter pair so
that a change event gets fired and bindings update.

So if you did:

  [Bindable]
  public var foo:int;

The compiler generates something like (the 12345 is a random number to
prevent name collisions):

  private var foo_12345;
  [Bindable(“propertyChange”)]
  public function get foo():int
  {
      return foo_12345;
  }
  public function set foo(value:int):void
  {
     if (value !== foo_12345)
     {
        foo_12345 = value;
        dispatchEvent(new Event(“propertyChange”));
     }
  }

If you put [Bindable] on the class definition, then all vars are
converted.  I get how that is a convenient way to save time writing code.

I suppose folks who use [Bindable] on getter/setters just want to save
time writing code, IMO, it isn’t worth it.  The Flex SDK hopefully never
does this, btw, because it is inefficient.  The inefficient pattern looks
like:

  private var _foo:int;
 
  [Bindable]
  public function get foo():int
  {
      return _foo;
  }
  public function set foo(value:int):void
  {
      _foo = value;
  }

This results in the compiler generating:

  private var _foo:int;

  [Bindable]
  public function get foo_12345():int
  {
      return _foo;
  }
  public function set foo_12345(value:int):void
  {
      _foo = value;
  }

  [Bindable(“propertyChange”)]
  public function get foo():int
  {
      return foo_12345;
  }
  public function set foo(value:int):void
  {
      if (value !== foo_12345)
      {
          foo_12345 = value;
          dispatchEvent(new Event(“propertyChange”));
      }
  }

Like I said, hopefully, the SDK code never does this and we always took
the time to do this:

  private var _foo:int;

  [Bindable(“fooChanged”)]
  public function get foo():int
  {
      return _foo;
  }
  public function set foo(value:int):void
  {
      if (_foo !== value)
      {
          _foo = value;
          dispatchEvent(new Event(“fooChanged”));
      }
  }

Yes, I had to do more typing, but if you compare the two patterns, you’ll
see that, for [Bindable] on interfaces and getter/setters, that you’ve
doubled the number of function calls required to get the value, and
tripled the number of function calls required to set the value, plus added
another not-so-short string to the string table and two functions to the
class traits in the SWF all of which have to be downloaded and decoded at
startup time.



Also, at runtime, the binding logic does an additional check if the
property change event is “propertyChange” to see if the property being
changes is the one it is interested in.

Will it make a huge difference in your app’s performance?  I don’t know
for sure, but I think it can add up over time.  Why wrap functions in
functions for no good reason?  Also, see [1] for old information on the
cost of function overhead.


Happy coding,
-Alex

[1] 
http://blogs.adobe.com/aharui/2007/10/actionscript_readwrite_perform_1.html

On 10/31/14, 7:05 AM, "Christofer Dutz" <christofer.d...@c-ware.de> wrote:

>Hi,
>
>
>After finishing the advanced-telemetry option I started working on the
>next problem. In this case a user annotated an Interface with "Bindable".
>Falcon dies with a NPE (ASCompilationUnit line 383). I first thought that
>it was an error to make an Interface bindable, but when looking through
>the internet, it should actually be possible to annotate an interface
>with a bindable annotation. The compiler has to do a little more checking
>though :-(
>
>
>I first thought of catching this situation and simply skipping it and
>reporting a warning, but I think this solution would not be correct as
>people are using this (I stumbled over it when trying to compile the
>flexicious code with falcon)
>
>
>Chris

Reply via email to