我编写了一个小类,用base64编码的JPEG bytearray创建一个圆形图像,但它似乎经常导致段错误。这是我在GJS中创建cairo表面的最简单方法,虽然我不反对Clutter,如果它解决了我的问题。
var CircularImage = new Lang.Class({
Name: "CircularImage",
Extends: Gtk.DrawingArea,
_init: function (bytearray, win, size) {
this.parent({
height_request: size,
width_request: size
});
this.size = size;
let image_stream = Gio.MemoryInputStream.new_from_data(
GLib.base64_decode(bytearray),
GLib.free
);
let pixbuf = GdkPixbuf.Pixbuf.new_from_stream(
image_stream,
null
)
pixbuf.scale_simple(this.size, this.size, GdkPixbuf.InterpType.HYPER);
this._surface = Gdk.cairo_surface_create_from_pixbuf(
pixbuf,
0,
win.get_window()
);
this.connect("draw", (widget, cr) => {
this._draw(widget, cr);
return false;
});
},
_draw: function (widget, cr) {
cr.setSourceSurface(this._surface, 0, 0);
cr.arc(this.size/2, this.size/2, this.size/2, 0, 2*Math.PI);
cr.clip();
cr.paint();
}
});
似乎没有针对CairoImageSurface的破坏功能或信号,我尝试不用pixbuf查看是否有帮助,但这会导致错误:
GLib-GObject-WARNING **:g_object_remove_toggle_ref:找不到切换参考号0x7f45456b19e0((nil))
我在一个简单的Gtk窗口中使用它并且它可以工作,但它似乎导致段错误大约一半的时间。我对内存管理知之甚少,因为我通常使用垃圾收集语言,所以我只假设这与内存有关,我没有释放。
有什么明显的东西我做错了,使用Clutter更简单的方法或简单的方法我可以追踪任意的段错误吗?
答案 0 :(得分:2)
即使底层库需要,您也不必处理GJS中的内存管理。如果你这样做,那就是一个bug。无论如何试图这样做肯定会导致崩溃。 (因此,即使您在GJS文档中看到任何调用GObject.unref()
或let image_stream = Gio.MemoryInputStream.new_from_bytes(
GLib.base64_decode(bytearray).toGBytes());
的说明 - 它们也会从C文档自动生成,不应该在那里。)
不幸的是,这些需要您关心内存管理的错误仍然存在,其中两个与您的代码段相关。
您现在遇到的错误就是这个:https://bugzilla.gnome.org/show_bug.cgi?id=747431 相反,做这样的事情:
draw
另一个可能在以后变得相关的GJS错误是,当您连接到cr.$dispose()
信号时,您当前必须在开罗上下文中调用material-content {
max-height: 100%;
overflow-y: scroll;
}
,否则内存将被泄露。