Во-первых, следует помнить о двух вещах:
Избегайте вызова низкоуровневых функций управления памятью, таких как GObject.run_dispose()
, поскольку в библиотеках C есть случаи, когда эти объекты кэшируются для повторного использования и не на самом деле утилизируются, когда вы думаете, что это так. Сигнал утилизации также отсутствует, и другим объектам может потребоваться уведомление.
Избегайте переопределения функций, запускающих удаление, таких как Clutter.Actor.destroy()
, и вместо этого используйте сигнал уничтожения. Сигнал обратного вызова GObject всегда получает исходящий объект в качестве первого аргумента, и можно безопасно использовать , что в обратном вызове уничтожения.
Есть несколько способов, которые я мог бы подумать решения этого, но это зависит от ситуации. Если функция asyn c является библиотечной функцией GNOME asyn c, она, вероятно, имеет отменяемый аргумент:
let cancellable = new Gio.Cancellable();
let actor = new Clutter.Actor();
actor.connect('destroy', () => cancellable.cancel());
Gio.File.new_for_path('foo.txt').load_contents_async(cancellable, (file, res) => {
try {
let result = file.load_contents_finish(res);
// This shouldn't be necessary if the operation succeeds (I think)
if (!cancellable.is_cancelled())
log(actor.width);
} catch (e) {
// We know it's not safe
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
log('it was cancelled');
// Probably safe, but let's check
else if (!cancellable.is_cancelled())
log(actor.width);
}
});
// The above function will begin but not finish before the
// cancellable is triggered
actor.destroy();
Конечно, вы всегда можете использовать отменяемый с Promise или просто обычная функция / шаблон обратного вызова:
new Promise((resolve, reject) => {
// Some operation
resolve();
}).then(result => {
// Check the cancellable
if (!cancellable.is_cancelled())
log(actor.width);
});
Другой вариант - null
из вашей ссылки, так как вы можете безопасно проверить это:
let actor = new Clutter.Actor();
actor.connect('destroy', () => {
actor = null;
});
if (actor !== null)
log(actor.width);