In researching this question I discovered the answer. I figured I'd add to the body of knowledge around these parts.
Per the documentation for matlab.mixin.Copyable
,
Given a call to the matlab.mixin.Copyable copy method of the form:
B = copy(A);
Under the following conditions, produces the described results:
A
has dynamic properties —copy
does not copy dynamic properties. You can implement dynamic-property copying in the subclass if needed.
A
has no non-Dependent properties —copy
creates a new object with no property values without calling the class constructor to avoid introducing side effects.
A
contains deleted handles —copy
creates deleted handles of the same class in the output array.
A
has attached listeners —copy
does not copy listeners. (emphasis added)
A
contains objects of enumeration classes — Enumeration classes cannot subclassmatlab.mixin.Copyable
.
A
delete method callscopy
—copy
creates a legitimate copy, obeying all the behaviors that apply in any other usage.
What I took this to mean originally was that a copy
call would skip over a property whose value is a listener handle. Apparently what it means is that rather than skipping the property altogether, copy
makes a reference to the original listener
object, i.e., it copies the handle to the listener but not the listener itself.
Of course, when you load
the copied object and it has that reference to listener, it'll complain:
Warning: Cannot load an object of class 'listener':
No matching constructor signature found.
Warning: During load:
An invalid default object has been detected while loading a heterogeneous array of
class event.listener. An empty array of class event.listener will be returned.
The easiest thing to do, then, is to modify saveobj
:
function sobj = saveobj(obj)
sobj = copy(obj);
sobj.hListener = [];
end
Here, I don't explicitly call delete
on the listener, as this would delete the actual object. Instead, I just clear the reference to that object.