2012-03-04 2 views
2

두 클래스, PlantGenerator이 있습니다. Generator은 벡터를 만들고 notify()을 통해 브로드 캐스트합니다 (Plant). classdef는 다음과 같습니다. 내 질문에 아무런 의미가 없으므로 실제 데이터 생성 방법은 포함하지 않았습니다. 나는 Generator 인스턴스를 삭제 한 후 생성 처음으로, 그것은 내가 Generator 인스턴스를 만드는 두 번째까지 소멸자를 실행하지 않습니다 수신기가 관련된 경우 MATLAB - 개체 소멸자가 실행되지 않음

classdef Plant < handle 
    properties 
     Listener 
    end 
    methods 
     function ListenerCallback(obj, data) 
      #% Perform an operation on data 
     end 
    end 
end 

classdef Generator < handle 
    properties 
     plant 
    end 
    events 
     newSignal 
    end 
    methods 
     function obj = Generator(plant) 
      obj.plant = plant; 
      obj.plant.Listener = addlistener(obj, 'newSignal', ... 
       @(src, data) obj.plant.ListenerCallback(data)); 
     end 
     function delete(obj) 
      delete(obj.plant.Listener); 
      disp('Generator instance deleted'); 
     end 
    end 
end 

은 내가 Generator 소멸자 정말 이상한 행동 것으로 나타났습니다. 다음은 그 예입니다.

>> P = Plant 
P = 
    Plant handle 

    Properties: 
    Listener: [] 
    Methods, Events, Superclasses 

>> G = Generator(P) 
G = 
    Generator handle 

    Properties: 
    plant: [1x1 Plant] 
    Methods, Events, Superclasses 
>> clear G #% DESTRUCTOR NOT CALLED?? 
>> G = Generator(P) 
Generator instance deleted #% why is the destructor run now? 
G = 
    Generator handle 

    Properties: 
    plant: [1x1 Plant] 
    Methods, Events, Superclasses 
>> clear G 
Generator instance deleted #% and why is the destructor run properly now? 

언제든지 내 소멸자가 실행되는 것이 중요합니다. 여기서 무슨 일이 일어나고 있고, 소멸자가 제대로 작동하게하려면 어떻게해야합니까? (난 그냥 모두 리스너를 제거하고이 작동하지 않을 경우 직접 Generator 인스턴스에서 Plant.ListenerCallback()를 호출 할 수 있습니다.)

편집 : 나는 clear G을 수행 할 때, 변수 G 작업 공간에서 제거 될 것 같은데 -하지만 Generator 개체는 P.Listener.Source에 있습니다. 이것이 소멸자가 호출되지 않는 이유입니다. 그래서 G을 삭제하여 P.Listener을 제거 할 수있는 방법이 없다고 생각합니다. 이걸 내가 원하는대로 할 수있는 방법이 있습니까? 아니면 그냥 붙어 있습니까?

+0

'삭제 G; 'clear G'가 아닌'clear G' 만? 문서에서 "그림 또는 다른 객체의 핸들을 지울 수 있지만 객체 자체는 제거되지 않습니다. 객체 및 파일을 제거하려면 delete를 사용하십시오. 핸들." – tmpearce

+0

@tmpearce - 작동하지 않습니다. 나는이 코드가 훨씬 더 큰 코드베이스의 일부이기 때문에'clear G' 만 사용하기를 희망했습니다. MATLAB을 사용하는 사람들과 함께 일하는 대부분의 사람들은'delete'와'clear' 사이에 차이점이 있는지 전혀 모릅니다. 그래서 이것은 매우 혼란 스러울 수 있습니다. –

+0

네, 이해합니다. 소멸자에 문제가 없기 때문에이 정보로 질문을 업데이트하고 싶은 경우가 있습니다. 객체에 'clear'가 포함되어 있기 때문입니다. – tmpearce

답변

1

왜 이상한 시간에 소멸자가 호출 되었습니까?

clear G #% DESTRUCTOR NOT CALLED?? 

가 새 Generator으로 P

G = Generator(P) 
Generator instance deleted #% why is the destructor run now? 

인스턴스화의 청취자의 G에 대한 참조가, 리스너는 덮어 쓰기됩니다. 더 이상 참조가 없기 때문에 Generator의 첫 번째 인스턴스의 소멸자를 호출합니다. (1) plant의 리스너가 새로운 Generator로 덮어 쓰기됩니다 :

G = 
    Generator handle 

    Properties: 
    plant: [1x1 Plant] 
    Methods, Events, Superclasses 
>> clear G 
Generator instance deleted #% and why is the destructor run properly now? 

은의 이전 단계에서 일이 다시 무엇을 살펴 보자. (2) 첫 번째 Generator의 소멸자를 호출합니다. (3) 소멸자가 청취자를 plant (!!!) (4) G의 작업 영역에서 지우고 이제는 새 Generator의 마지막 남은 인스턴스입니다. 따라서 clear G은 클래스 소멸자를 호출합니다. 당신이 clear 대신 delete의 사용을 허용 할


하나하지 - 꽤 방법은 clear 명령

function clear(varargin) 

%# check for Generator objects 
isGenerator = cellfun(@(x)evalin('caller','isa(x,''Generator'');'),varargin); 

%# I loop here b/c I don't have the time to carefully construct 
%# the evalin commands 
%# Generator gets deleted, everybody else gets cleared 
for i=1:nargin 
    if isGenerator(i) 
     evalin('caller',sprintf('delete %s',varargin{i})); 
    else 
     evalin('caller',sprintf('builtin(''clear'',''%s'');',varargin{i}); 
    end 
end 
+0

위대한 설명. 못생긴하지만 직선적 인 해결 방법. 언제나처럼 고마워. –

1

아마도 내가 2 년 오래된 질문을 부활하고 있습니다를 오버로드 할 수 있지만 것입니다 ..

Matlab은 소멸자를 깨끗하게 호출하려고합니다. 문제는 청취자를 어떻게 정의했는지에 있습니다.

obj.plant.Listener = addlistener(obj, 'newSignal', ... 
       @(src, data) obj.plant.ListenerCallback(data)); 

이렇게하면 obj에 대한 하드 코드 된 참조가있는 익명의 함수가 생성됩니다. obj가 다른 곳 (예 : 기본 작업 영역에서 삭제)을 통해 범위를 벗어나면 여전히 익명 함수에 계속 존재합니다. 대신 다음을 정의하면

obj.plant.Listener = addlistener(obj, 'newSignal', ... 
      @(src, data) src.plant.ListenerCallback(data)); 

익명 함수에 하드 코딩 된 참조가 없습니다. 리스너 콜백의 첫 번째 인수는 항상 호출 된 객체이지만 익명 함수에서 객체 참조를 하드 코딩하지 않고 즉시 가져옵니다.

희망은 여전히 ​​가치가 있습니다.

관련 문제