フィルターのクリア

Maintaining links to handle objects after saving to Mat file

5 ビュー (過去 30 日間)
Steven
Steven 2023 年 11 月 19 日
コメント済み: Walter Roberson 2023 年 11 月 20 日
I am trying to save objects that have properties that are handle classes. This seems to work only if I load and save the full workspace, as opposed to just the objects being referenced. Here is an example. Define two handle classes
classdef PartA < handle
properties (SetAccess = immutable)
ID(1,1) int32 = 1;
end
properties
SN(1,1) int32
Radius(1,1) double
end
end
classdef PartB < handle
properties (SetAccess = immutable)
ID(1,1) int32 = 1;
end
properties
SN(1,1) int32
Diameter(1,1) double
end
end
Define a class that has these classes as properties:
classdef Assembly < handle
properties (SetAccess = immutable)
ID = 3;
end
properties
SN
A(1,1) PartA
B(1,1) PartB
end
end
Create instances and manipulate:
% Part instances:
A1 = PartA;
A1.SN = 1;
A1.Radius = 1;
A2 = PartA;
A2.SN = 2;
A2.Radius = 1;
B1 = PartB;
B1.SN = 1;
B1.Diameter = 1;
B2 = PartB;
B2.SN = 2;
B2.Diameter = 1;
% Assembly instances:
Assem1 = Assembly;
Assem1.SN = 1;
Assem1.A = A1;
Assem1.B = B1;
Assem2 = Assembly;
Assem2.SN = 2;
Assem2.A = A2;
Assem2.B = B2;
% Change a part within an Assembly
Assem1.A.Radius = 10;
% See it reflected in the handle
disp('Changes before save:')
disp('Radius in Assembly:')
disp(Assem1.A.Radius)
disp('Radius in handle:')
disp(A1.Radius)
save Parts.mat
clear
load Parts.mat
% Change a part within an Assembly
disp('Changes after loading full mat file:')
Assem1.A.Radius = 100;
% See it reflected in the handle
disp('Radius in Assembly:')
disp(Assem1.A.Radius)
disp('Radius in handle:')
disp(A1.Radius)
save Parts.mat
% Now load just one assembly and test
clear
load('Parts.mat','A1','B1','Assem1')
disp('Changes after loading Assembly and parts handles:')
Assem1.A.Radius = 1000;
% See it reflected in the handle
disp('Radius in Assembly:')
disp(Assem1.A.Radius)
disp('Radius in handle:')
disp(A1.Radius)
save('Parts.mat','A1','B1','Assem1','-append')
% Now load just one assembly and test after appended save
clear
load('Parts.mat','A1','B1','Assem1')
disp('Changes after loading Assembly and parts handles after append save:')
Assem1.A.Radius = 10000;
% See it reflected in the handle
disp('Radius in Assembly:')
disp(Assem1.A.Radius)
disp('Radius in handle:')
disp(A1.Radius)
disp('Link is broken')
I understand that the appended save would need to include all the handles references (in this case A1 and A2 as part of Assem1), but it appears that for the links to work you need to load and save the whole mat file. This seems to require a whole lot of loading and saving of data that is not relavent. Quick tests using the matfile interface don't seem to work either.

回答 (1 件)

Walter Roberson
Walter Roberson 2023 年 11 月 19 日
When you load() a handle, the handle you get back is not the same as the original handle. This is the case even if the class is fairly simple (does not have any properties that were discarded during serialization)
Suppose for example that you savefig(), which a bit of fancy decoration around save() of a figure handle. If you have the figure still open, and you openfig() or load() from the .fig file, should you get back a handle to the same figure, or should you get back a handle to a different figure that has the same state as what was saved?
If you believe that you should get back a handle to the same figure, then what if the user had (for example) minimized the figure to dock in the meanwhile. Then the state of the existing figure is not the same as the state of the saved figure: should MATLAB be using the same figure handle, and yet with some kind of "view" onto it so that if you look with the old reference you see it docked but with the new view that you see it open (because that was what was saved) -- and yet somehow they are to be the same figure handle?
If even one bit of state has changed in the live figure, including if the user moved it a few centimeters, then there is a mismatch between live state and saved state. Is it your opinion that in such cases, as MATLAB loads the saved figure, it should be comparing the state details of the saved figure to every existing figure, and if it finds an exact duplicate (the live figure has not changed in any respect) then it should return back the handle to the live figure, but otherwise it should return back a new handle?
  5 件のコメント
Steven
Steven 2023 年 11 月 19 日
I find it strange that the behavior for loading and saving a whole workspace is different that loading parts of the matfile and saving with append. Despite your valid concerns, the objects do link on save and load of the whole workspace but do not link when the save is an append.
Walter Roberson
Walter Roberson 2023 年 11 月 20 日
append mode of save() works by first serializing the parameter variables, then writing those to the end of the .mat file (usually in compressed form), then going back through the file and marking any existing variable with the same name as being an unused block.
append mode of save does not even search to determine whether there is a large enough free block in the file to hold the new information.
append mode is intended to be a fast way to add data. It doesn't analyze the existing data except for the variable names and sizes .

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeClass Introspection and Metadata についてさらに検索

製品


リリース

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by