XComponent 接口

From Apache OpenOffice Wiki
Jump to: navigation, search



引用计数系统的一个主要问题是循环引用。假定对象 A 引用对象 B,而 B 直接或间接地引用对象 A。即使释放对 A 和 B 的所有外部引用,也不会析构对象,这会导致资源泄漏。

循环引用
Documentation note.png 一般来说,Java 开发者不必担心这种问题,因为垃圾收集器算法可以检测循环引用。但是,在 UNO 中,人们决不会知道对象 A 和对象 B 是否真正存在于同一 Java 虚拟机中。如果存在于同一 Java 虚拟机中,循环引用被真正进行垃圾收集。如果不存在于同一 Java 虚拟机中,对象就会泄漏,因为 Java VM 无法在 VM 外检查是否存在对该对象的引用。


在 UNO 中,开发者必须明确决定何时中断循环引用。为了支持此概念,提供了 com.sun.star.lang.XComponent 接口。废止一个 XComponent 时,会通知希望得到通知的其他对象。

  // within the module com::sun::star::lang
  // when dispose() is called, previously added XEventListeners are notified
  interface XComponent: com::sun::star::uno::XInterface
  { 
       void dispose(); 
       void addEventListener( [in] XEventListener xListener ); 
       void removeEventListener( [in] XEventListener aListener ); 
  };
 
  // An XEventListener is notified by calling its disposing() method
  interface XEventListener: com::sun::star::uno::XInterface
  { 
     void disposing( [in] com::sun::star::lang::EventObject Source ); 
  };

其他对象可以将其自身作为 com.sun.star.lang.XEventListener 添加到 XComponent 中。调用 dispose() 方法时,对象通过 disposing() 方法通知所有 XEventListener ,并释放所有接口引用,从而中断循环引用。

对象 C 调用对象 B 的 XComponent 中的 dispose()


一个已废止的对象不能够遵守其规范,因此,需要确保调用某个对象之前没有废止该对象。为此,UNO 使用所有者/用户概念。仅允许一个对象的所有者调用 dispose 方法,而且每个对象只能有一个所有者。所有者始终可以自由地废止该对象。一个对象的用户知道该对象随时可能会被废止。用户加入一个事件侦听器来发现对象何时被废止。当用户得到通知时,用户释放对该对象的接口引用。在这种情况下,用户不得调用 removeEventListener(),因为废止的对象释放了对此用户的引用。

Documentation caution.png 所有者/用户概念的一个主要问题是必须始终有人调用 dispose()。设计服务和接口时,必须考虑这一点,并且必须明确指定。

这将解决上述问题。但是,还必须满足几个条件。

B 释放所有接口引用,这会导致析构对象 A,然后对象 A 释放对对象 B 的引用,因而中断循环引用。

如果在废止一个对象的同时调用该对象,该操作将会是被动的。例如,如果调用 removeListener(),该调用应该被忽略。如果在某个对象不能再遵守其接口规范时调用方法,就应该抛出一个从 com.sun.star.uno.RuntimeException 派生的 com.sun.star.lang.DisposedException。这是实现应该抛出 RuntimeException 的少见情形之一。上述情形通常在多线程环境中发生,即使调用程序已经添加一个事件侦听器来避免调用所有者废止的对象。


所有者/用户概念不会总是合适,尤其是在有多个可能的所有者的情况下。在这些情况下,不应该存在所有者,仅应该存在用户。在多线程方案中,可能会多次调用 dispose()。对象的实现应该能够处理这种情形。


不仅在调用 dispose() 时,而且在删除对象时,XComponent 实现应该始终通知 disposing() 侦听器对象将要被析构。删除对象后,该对象的引用计数减少到零。当侦听器不包含对广播器对象的引用时,就可能发生这种情况。


只有一个所有者,而没有其他用户时,不必实现 XComponent


Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages