слушатель это метод, который вызывается при опреленных условиях
в данном случае когда i==0
чтобы отследить это, i должна быть геттером/сеттером
простейший случай - собственный метод: в сеттере проверяем, вызываем метод

Код AS1/AS2:
class PropWatcher
{
private var _i:Number;
private function onZero()
{
trace( "onZero listener " );
}
public function get i():Number { return _i; }
public function set i(value:Number):Void
{
if (_i != value)
{
_i = value;
if (_i == 0) onZero()
}
}
}
///////////////////////
var test:PropWatcher = new PropWatcher();
test.i = 0;
если нужно вызывать одноименные обрабочики в других объектах, то можно воспользоваться методами AsBroadcaster (добавив их к экземпляру через AsBroadcaster.initialize), тогда у всех объектов, подписанных на прослушку экземпляра PropWatcher срабоатет метод onZero

Код AS1/AS2:
class PropWatcher
{
private var _i:Number;
private var broadcastMessage:Function;
public var addListener:Function;
public var removeListener:Function;
public function PropWatcher()
{
AsBroadcaster.initialize(this);
}
public function get i():Number { return _i; }
public function set i(value:Number):Void
{
if (_i != value)
{
_i = value;
if (_i == 0) broadcastMessage("onZero");
}
}
}
//////////////////////////////////////
var test:PropWatcher = new PropWatcher();
test.addListener(this);
test.i = 0;
function onZero()
{
trace( "onZero listener " );
}
ну и наконец можно посмотреть в mx.events.EventDispatcher
в целом схема такая же как и с AsBroadcaster, но подписывается на прослушку не объект, имеющий одноименный событию метод, а вообще любой метод, что бывает удобнее