引用计数助手

RefPtr 与 nsCOMPtr

一般的经验法则是,当 T 是从 nsISupports 继承的接口类型时,使用 nsCOMPtr<T>;当 T 是具体类型时,使用 RefPtr<T>

此基本规则源于一些 nsCOMPtr<T> 代码被分解到 nsCOMPtr_base 基类中,该基类将指针存储为 nsISupports*。此设计旨在节省二进制文件中的某些空间(尽管目前尚不清楚它是否仍然如此)。由于 nsCOMPtr 将指针存储为 nsISupports*,因此必须能够从 T* 无歧义地转换为 nsISupports**。许多具体类从多个 XPCOM 接口继承,这意味着它们不能与 nsCOMPtr 一起使用,这导致建议对这些类使用 RefPtr

nsCOMPtr<T> 还要求目标类型 TQueryInterface 的有效目标,以便它可以断言存储的指针是规范的 T 指针(即 mRawPtr->QueryInterface(T_IID) == mRawPtr)。

do_XXX() nsCOMPtr 助手

代码库中有很多 do_XXX 助手方法可以分配到 nsCOMPtr(有时是 RefPtr)中,以根据目标指针类型执行显式操作。

通常,当这些操作成功时,它们将使用有效值初始化智能指针,否则它们将静默地将智能指针初始化为 nullptr

do_QueryInterfacedo_QueryObject

尝试使用 XPCOM QueryInterface 机制将提供的对象转换为目标类。通常,do_QueryInterface 只能用于在 nsCOMPtr<T> 中的接口类型之间进行转换,而 do_QueryObject 则用于向下转换为具体类型的情况。

do_GetInterface

使用 nsIInterfaceRequestor 接口查找实现请求接口的对象。如果目标对象未实现 nsIInterfaceRequestor 或未提供给定的接口,则使用 nullptr 初始化智能指针。

do_GetService

在组件管理器中查找由传入的 CID 或 ContractID 字符串定义的组件,并返回指向服务实例的指针。如果服务尚未启动,这可能会启动服务。生成的服

do_CreateInstance

在组件管理器中查找由传入的 CID 或 ContractID 字符串定义的组件,创建并返回一个新实例。生成的

do_QueryReferentdo_GetWeakReference

当传递 nsIWeakReference*(例如来自 nsWeakPtr)时,do_QueryReferent 尝试重新获取对持有类型的强引用,并使用 QueryInterface 将其转换为目标类型。如果这些步骤中的任何一个失败,则使用 nullptr 初始化智能指针。

相反,do_GetWeakReference 执行相反的操作,使用 QueryInterface 将类型转换为 nsISupportsWeakReference*,并获取对传入对象的 nsIWeakReference*