我有一個Gtk.Box的子類,它包含一個GLib.Timer,它在給定時間間隔後觸發通知。我在這個類中調用了Gtk.Box上的this.destroy()方法。計時器繼續運行,即使在其父實例被銷燬後也會觸發通知。已經銷燬的這個類的所有實例都表現出這種行爲並繼續使用CPU和內存,直到進程終止。銷燬類實例並不會終止它在vala中擁有的實例
我該如何解決這個問題?如何有效殺死實例,以及如何手動釋放內存而不是依賴vala的垃圾回收。
編輯:這裏是一個(尷尬)mvce
// mvce_deletable
// nine
// 2017.01.11
// valac --pkg gtk+-3.0 --pkg glib-2.0 deletablebox.vala
using Gtk;
using GLib;
class RemovableBox : Gtk.Box {
private Gtk.Button delete_button;
private GLib.Timer timer;
private Gtk.Label label;
public RemovableBox() {
delete_button = new Gtk.Button.with_label ("DESTROY");
delete_button.clicked.connect (()=>{this.destroy();});
this.add (delete_button);
label = new Gtk.Label ("0000000");
this.add (label);
timer = new GLib.Timer();
timer.start();
Timeout.add (50, update);
this.show_all();
}
private bool update() {
if (timer.elapsed() > 10.0f) {
stdout.printf("and yet it breathes\n");
}
label.set_text ("%f".printf(timer.elapsed()));
return true;
}
}
int main (string [] args) {
Gtk.init(ref args);
var window = new Gtk.Window();
window.destroy.connect (Gtk.main_quit);
var delete_me = new RemovableBox();
window.add (delete_me);
window.show_all();
Gtk.main();
return 0;
}
我加了一個timer_id的的RemovableBox類,但它仍期望不起作用。
class RemovableBox : Gtk.Box {
private Gtk.Button delete_button;
private uint timeout_id;
private GLib.Timer timer;
private Gtk.Label label;
public RemovableBox() {
delete_button = new Gtk.Button.with_label ("DESTROY");
delete_button.clicked.connect (()=>{this.destroy();});
this.add (delete_button);
label = new Gtk.Label ("0000000");
this.add (label);
timer = new GLib.Timer();
timer.start();
timeout_id = Timeout.add (40, update);
this.show_all();
}
~ RemovableBox() {
Source.remove (timeout_id);
}
private bool update() {
if (timer.elapsed() > 10.0f) {
stdout.printf("and yet it breathes\n");
}
label.set_text ("%f".printf(timer.elapsed()));
return true;
}
}
我甚至沒有意識到Vala的RAII到現在爲止。在堆棧上也分配了非GObject類(如在C++中)? –
維基百科文章引用了C++和堆棧。我認爲這對於一般的RAII概念有點誤導。在Vala中,釋放資源的調用是由Vala編譯器以與創建它們相反的順序創建的。所以你可以在try塊中引發一個「異常」,並且析構函數會反向調用,這樣就可以正確釋放資源。這是另一個問題,雖然:) – AlThomas
所以我宣佈timer_id作爲一個uint和修改類像你說的,但它仍然不能按需要工作。 – Nine