https://developer.gnome.org/glib/unstable/glib-GVariant.html#g-variant-ref-sink
我已经阅读了上面的glib手册,其中说:" GVariant使用浮动引用计数系统.所有函数的名称都以g_variant_new_返回浮动引用开头. "但浮动引用计数的实际描述在哪里?我找不到它的全面描述.
特别是我想要了解什么时候需要引用一个变体,何时不需要.例如:
GVariant *a_v = g_variant_new_boolean(TRUE);
GVariant *another_v = g_variant_new("v", a_v);
Run Code Online (Sandbox Code Playgroud)
a_v它,因为它被第二个消耗掉了g_variant_new.那是对的吗?another_v(假设从那时起another_v没有传递给任何其他内容)?在GObject参考手册中有一个关于浮动引用的部分,它更详细.浮动引用可能看起来有点模糊,但它们对C非常有用,因此花几分钟时间来真正理解它们是一个好主意.
我将假设您了解引用计数的工作原理 - 如果没有很多文档,请花几分钟时间阅读.
首先,让我们看看如果g_variant_new_boolean返回常规引用,您的示例会发生什么.当您第一次获得该值时,引用计数将为1.当您将其传递给时g_variant_new,g_variant_new将引用计数增加到2.在某些时候,我假设您将被处置another_v,此时引用计数a_v将降至1 ...但请记住,直到引用计数达到0才会释放内存.
为了解决这个问题,您有两种选择.首先是g_variant_new窃取来电者的参考,这基本上是一个解决方案.当你打电话g_variant_new(或任何类似的功能)时,你会放弃你的参考,所以在将来你需要手动参考a_v每次你想把它传递给别的东西.
另一种选择是在完成后手动取消它.这不是世界末日,但是很容易忘记做错或做错(比如忘记在错误路径中取消它).
而GVariant所做的是返回"浮动"参考.想到它的最简单的方法(恕我直言)是第一次g_variant_ref被称为它并没有真正做任何事情 - 它只是"沉没"浮动参考.引用计数从1到1. 然后g_variant_ref,后续调用将增加引用计数.
现在让我们看看你的例子实际发生了什么. g_variant_new_boolean返回浮动引用.然后将其传递给g_variant_new调用g_variant_ref浮点引用的调用.引用计数现在为1,当another_v引用计数达到0时a_v,引用计数将递减,在这种情况下达到0,所有内容都将被释放.你不需要打电话g_variant_unref.
然而,关于浮动引用的很酷的部分就是这样的事情:
GVariant *a_v = g_variant_new_boolean(TRUE);
GVariant *another_v = g_variant_new("v", a_v);
GVariant *yet_another_v = g_variant_new("v", a_v);
Run Code Online (Sandbox Code Playgroud)
当g_variant_new第二次调用时a_v,refcount将再次递增(至2).g_variant_ref在传递a_v给g_variant_new第二次之前无需调用- 第一次调用看起来就像第一次调用一样,并且一致性是API中非常好的功能.
在这一点上它可能是显而易见的,但是,是的,你确实需要调用g_variant_unref上another_v(和,在最后一个例子,yet_another_v).
| 归档时间: |
|
| 查看次数: |
2016 次 |
| 最近记录: |