面向对象事件在ABAP中十分重要,并且很容易处理。
我们需要handler方法来注册事件:
METHODS : handle_event_raised FOR EVENT event_raised OF lcl_event_raiser.
然后把它设置为事件处理器:
SET HANDLER me->handle_event_raised FOR i_raiser.
ABAP开发者像上面这样使用事件处理器,但是其中的很多人不关心事件的解除注册。为什么我们需要注意事件的解除注册?
下面的简单代码可以解释事件处理的重要性:
CLASS lcl_event_raiser DEFINITION FINAL. PUBLIC SECTION. EVENTS : event_raised. CLASS-METHODS : start. PRIVATE SECTION. CLASS-DATA : m_object TYPE REF TO lcl_event_raiser. METHODS : raise_event. ENDCLASS. CLASS lcl_event_handler DEFINITION FINAL. PUBLIC SECTION. METHODS : handle_event_raised FOR EVENT event_raised OF lcl_event_raiser. METHODS : constructor IMPORTING i_raiser TYPE REF TO lcl_event_raiser i_number TYPE i. PRIVATE SECTION. DATA : m_handler TYPE i. ENDCLASS. CLASS lcl_event_raiser IMPLEMENTATION. METHOD start. CREATE OBJECT m_object. DO 3 TIMES. DATA(l_handler) = NEW lcl_event_handler( i_raiser = m_object i_number = sy-index ). m_object->raise_event( ). FREE l_handler. ENDDO. m_object->raise_event( ). ENDMETHOD. METHOD raise_event. RAISE EVENT event_raised. ENDMETHOD. ENDCLASS. CLASS lcl_event_handler IMPLEMENTATION. METHOD constructor. SET HANDLER me->handle_event_raised FOR i_raiser. me->m_handler = i_number. ENDMETHOD. METHOD handle_event_raised. WRITE : / me->m_handler. ENDMETHOD. ENDCLASS. START-OF-SELECTION. lcl_event_raiser=>start( ).
结果如下 :
如你所见,程序创建并且释放了第一个对象,但是触发事件依然捕捉到了这个对象。这是因为使用free释放对象是不够的。一旦对象的事件被注册,运行时会保有该对象,直到事件解除注册。
我们可以通过简单的代码解除注册:ACTIVATION SPACE。
只需要添加了一点点代码来处理对象:
........ * Definition part METHODS : free. ........ ........ * Implementation Part METHOD free. SET HANDLER me->handle_event_raised FOR i_raiser ACTIVATION SPACE. * Other data you want to clear, refresh or free CLEAR : me->m_handler. ENDMETHOD.
并且让start方法变为这样:
........... METHOD start. CREATE OBJECT m_object. DO 3 TIMES. DATA(l_handler) = NEW lcl_event_handler( i_raiser = m_object i_number = sy-index ). m_object->raise_event( ). l_handler->free( ). FREE l_handler. ENDDO. m_object->raise_event( ). ENDMETHOD. .........
结果如下:
这样一来,我们就不需要额外关心事件的解除注册了。
想象下你需要处理两三个、甚至更多ALV,并且还要触发它们的一些事件的时候。如果你没有解除注册,运行时总会找到本该已释放的对象,这样就会导致dump、不必要的处理等等。为了避免这些情况,我们需要解除事件的注册。