微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何正确处理 GLib 中的浮动引用参数?

如何解决如何正确处理 GLib 中的浮动引用参数?

GLib 中有浮动引用对象。

container = create_container();
container_add_child(container,create_child());

在本例中,create_child 函数创建了不属于任何人的 浮动 对象。 container_add_child 函数获取对象的所有权并成为对象的唯一所有者。当它否认该对象时,该对象被释放。

但是如果 container_add_child 函数没有取得对象的所有权怎么办?在这种情况下,我们会出现内存泄漏。是的,该对象不属于任何人,但它仍然存在于内存中,并且没有人释放该对象的内存。

如果我们编写一个将此类对象作为参数的函数会怎样。

void handle_object(gpointer object)
{
    g_object_ref_sink(object);
    
    // Doing something with object
    
    g_object_unref(object);
}

我们是否必须将 g_object_ref_sink / g_object_unref 添加到每个将潜在浮动引用对象作为参数的函数?如果我们删除这些行,那么有人可能会发出这样的调用handle_object(create_child()) 并且我们会得到内存泄漏。该对象将永远“浮动”在内存中。

解决方法

我们是否必须将 g_object_ref_sink / g_object_unref 添加到每个将潜在浮动引用对象作为参数的函数?

是的,这就是围绕浮动引用构建 API 很痛苦的原因之一。最好不要使用它们,而是使用显式 ownership transfer annotations(transfer none)(transfer full))。

,

我们是否必须将 g_object_ref_sink / g_object_unref 添加到每个将潜在浮动引用对象作为参数的函数?如果我们删除这些行,那么有人可能会进行这样的调用:handle_object(create_child()) 并且我们将得到内存泄漏。该对象将永远“浮动”在内存中。

智者的问题包含了一半的答案。 将 ref/unref 添加到您使用的任何对象是个好主意。在单线程应用程序或 GUI 方法中可能不是这种情况,您可以 100% 确定甚至没有人有可能销毁对象。但在多线程应用程序中,对象可以随时取消引用,这将导致该对象失效。

但是,在使用 GTK 5 年后,我不清楚需要两个单独的方法(ref_sinkref):)

,

试图回答我的问题。

我们是否必须将 g_object_ref_sink / g_object_unref 添加到每个将潜在浮动引用对象作为参数的函数?

我想说,不要将“潜在地” 浮动引用传递给不期望它们的函数。浮动引用是特殊的。您无法访问浮动引用所引用的对象,因为您不拥有它(没有人拥有它)。在使用此类对象之前,您必须调用 g_object_ref_sink 以获取所有权。或者传递对拥有所有权的函数的引用(但是在调用这样的函数之后,您仍然无法使用该对象,因为您仍然不拥有它)。

因此,如果函数假定您拥有该对象,请不要将浮动引用传递给它。在这种情况下,您不必将 g_object_ref_sink / g_object_unref 添加到此类函数中。

如果由于某些原因,函数“可能”采用浮动引用,那么,是的,您必须向其添加 g_object_ref_sink / g_object_unref。但是,如果该函数不将引用存储在某处以供以后使用,则该函数可能设计得很糟糕。如果函数仅在本地使用该对象(仅在调用期间),则不要向其添加 g_object_ref_sink / g_object_unref,也不要向其传递浮动引用。如果该函数保存引用以供以后使用,则必须向其中添加 g_object_ref_sink 以获取所有权。但在这种情况下,此函数中将不会有 g_object_unref 调用,因为稍后有人将在函数退出后使用该引用。

所以我想说,将一对 g_object_ref_sinkg_object_unref 添加到函数中是不行的。只需添加 g_object_ref_sink 以获得所有权,以便在函数退出后稍后使用引用,就可以了。

是的,这让事情变得困难,因为您必须始终关心引用是否浮动。这就是为什么我个人不喜欢浮动参考的想法。但在向容器添加新对象等情况下,这也使事情变得更容易。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?