Эталонный цикл закрытия Vala
Я пишу класс в Vala, где я связываю два одинаковых свойства объекта вместе с замыканием для преобразования одного в другое.
class Foo : Object
{
public int num { get; set; }
public int scale = 2;
public int result { get; set; }
construct {
this.bind_property("num", this, "result", 0,
(binding, src, ref dst) => {
var a = src.get_int();
var b = this.scale;
var c = a * b;
dst.set_int(c);
}
);
}
}
Закрытие сохраняет ссылку
this
(потому что я использую
this.scale
), который создает цикл ссылок, который поддерживает мой класс даже тогда, когда все другие ссылки на него потеряны.
Привязка будет удалена только тогда, когда счетчик ссылок достигнет 0, но счетчик ссылок достигнет 0 только после удаления привязки и ее закрытия.
Есть ли способ сделать ссылку на закрытие
this
слабый? Или проверить, когда счетчик ссылок достигнет 1, чтобы удалить его?
2 ответа
Это известная неэффективность компилятора Vala, которая обсуждается в этом выпуске.
На данный момент проблемы можно избежать, выполнив привязку из статического метода, в котором закрытие не захватывает
this
.
class Foo : Object
{
public int num { get; set; }
public int scale = 2;
public int result { get; set; }
construct {
this.bind_properties(this);
}
private static void bind_properties(Foo this_)
{
weak Foo weak_this = this_;
this_.bind_property("num", this_, "result", 0,
(binding, src, ref dst) => {
var a = src.get_int();
var b = weak_this.scale;
var c = a * b;
dst.set_int(c);
}
);
}
}
Не проверено, но можете ли вы назначить
this
на слабую переменную и ссылку на нее в закрытии? Например:
weak Foo weak_this = this;
this.bind_property(…, (…) => {
…
b = weak_this.scale;
…
}