Очистка подписок на события объекта - PullRequest
0 голосов
/ 17 мая 2018

Я использую BreezeJS.Предположим, у нас есть пользовательский класс EntityBase и мы подписаны на некоторые entityAspect события (propertyChanged, validationErrorsChanged) и / или на события его свойств коллекции (arrayChanged) в его методе инициализации сущности (пример ниже).находится в TypeScript):

import { Entity, EntityAspect } from "breeze-client";

export abstract class EntityBase implements Entity {
    public static initializer(entity: EntityBase): void {
        const entityAspect: EntityAspect = entity.entityAspect;

        entityAspect.propertyChanged.subscribe(EntityBase.propertyChangedHandler);
        entityAspect.validationErrorsChanged.subscribe(EntityBase.validationErrorHandler);
    }
}

export class Contact extends EntityBase {
    /// [Initializer]
    public static initializer(entity: EntityBase): void {
        super.initializer(entity);

        (entity as Contact).addresses.arrayChanged.subscribe(Contact.addressesChangedHandler);
    }
    /// </code>

    // Generated code. Do not place code below this line.
    public addresses: Address[];
}

        // Somewhere where MetadataStore is initialized.
        metadataStore.registerEntityTypeCtor("Contact", Contact, Contact.initializer);

Это означает, что в какой-то момент времени между отсоединением сущности и перед его сборкой мусора мы должны отписаться от этих событий, чтобы предотвратить утечки памяти.Таким образом, нам нужно иметь финализатор / деструктор сущности.

Я не вижу каких-либо очевидных дополнительных модулей в жизненном цикле сущности для этого в Breeze API.

Может кто-нибудьдать представление о том, как это сделать?

1 Ответ

0 голосов
/ 05 февраля 2019

Хорошо, я думаю, что понимаю вопрос.Но чтобы убедиться, позвольте мне переформулировать проблему и добавить некоторый контекст.Как только сущность отсоединяется, она будет собирать мусор, если вы не сохраните отдельную ссылку на нее.Эта сборка мусора также будет собирать любые подписки, сделанные на «entityAspect» каждого объекта.Таким образом, единственный способ увидеть утечку (после сборки мусора) - это сохранить подписку на некоторый объект отдельно от самого объекта (или его EntityAspect).В вашем случае мне неясно, являются ли определенные вами обработчики EntityBase статическими или уровня экземпляра, но если статические, то вам нужно будет отписаться.

Для этого в Breeze EntityManager есть событие entityChanged , которое можно использовать следующим образом:

var em = new EntityManager( {serviceName: "api/NorthwindIBModel" });
em.entityChanged.subscribe(function(changeArgs) {
    // This code will be executed any time any entity within the entityManager is added, 
    // modified, deleted or detached for any reason. 
    var action = changeArgs.entityAction;
    var entity = changeArgs.entity;
    // unsubscribe here if detaching.
});

Имеет ли это смысл?

...