本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

句柄对象行为

多个变量可以引用同一个句柄对象。因此,用户与句柄类的实例的交互不同于值类的实例。了解句柄对象的行为可以帮助您确定是实现句柄还是值类。本主题说明其中的一些交互。

有关句柄类的详细信息,请参阅句柄类

什么是句柄?

句柄是特定类型的 MATLAB® 对象。当变量保存句柄时,它实际上保存的是对相应对象的引用。

句柄对象允许多个变量引用同一个对象。句柄对象行为会影响复制句柄对象以及将它们传递给函数时发生的事情。

句柄的副本

句柄对象变量的所有副本都引用同一个底层对象。这种引用行为意味着,如果 h 标识某个句柄对象,则:

h2 = h;

创建另一个变量 h2,它引用与 h 相同的对象。

例如,MATLAB audioplayer 函数创建一个包含音频源数据的句柄对象,以重现特定的声音片段。audioplayer 函数返回的变量可标识音频数据,并允许您访问对象函数来播放音频。

MATLAB 软件包含音频数据,您可以加载这些数据并使用它们创建 audioplayer 对象。以下示例会加载音频数据、创建音频播放器,并播放音频:

load gong Fs y
gongSound = audioplayer(y,Fs);
play(gongSound)

假设您将 gongSound 对象句柄复制到另一个变量 (gongSound2):

gongSound2 = gongSound;

变量 gongSoundgongSound2 是同一句柄的副本,因此引用的是同一音频源。使用任一变量访问 audioplayer 信息。

例如,通过为 SampleRate 属性赋一个新值来设置锣声音频源的采样率。首先获取当前采样率,然后设置新采样率:

sr = gongSound.SampleRate;
disp(sr)
8192
gongSound.SampleRate = sr*2;

您可以使用 gongSound2 访问同一音频源:

disp(gongSound2.SampleRate)
16384

以新采样率播放锣声:

play(gongSound2)

在函数中修改过的句柄对象

将实参传递给函数时,函数会将变量从调用该函数的工作区复制到函数工作区的形参变量中。

将非句柄变量传递给函数不会影响调用方工作区中的原始变量。例如,myFunc 会修改名为 var 的局部变量,但当函数结束时,局部变量 var 便不再存在:

function myFunc(var)
   var = var + 1;
end

定义一个变量,并将其传递给 myfunc

x = 12;
myFunc(x)

执行 myFunc(x) 后,x 的值没有更改:

disp(x)
12

myFunc 函数可以返回修改后的值,您可以将该值赋给同一个变量名称 (x) 或另一个变量。

function out = myFunc(var)
   out = var + 1;
end

修改 myfunc 中的值:

x = 12;
x = myFunc(x);
disp(x)
13

当参数是句柄变量时,函数只复制句柄,而不复制由该句柄标识的对象。两个句柄(原始句柄和本地副本)引用同一个对象。

当函数修改对象句柄引用的数据时,可以从调用工作区的句柄变量中访问这些更改,而不需要返回修改后的对象。

例如,使用 modifySampleRate 函数更改 audioplayer 的采样率:

function modifySampleRate(audioObj,sr)
   audioObj.SampleRate = sr;
end

创建一个 audioplayer 对象,并将其传递给 modifySampleRate 函数:

load gong Fs y
gongSound = audioplayer(y,Fs);
disp(gongSound.SampleRate)
8192
modifySampleRate(gongSound,16384)
disp(gongSound.SampleRate)
16384

modifySampleRate 函数不需要返回修改后的 gongSound 对象,因为 audioplayer 对象是句柄对象。

确定对象是否为句柄

句柄对象是 handle 类的成员。因此,您始终可以使用 isa 函数将对象标识为句柄。测试句柄变量时,isa 返回逻辑值 true (1):

load gong Fs y
gongSound = audioplayer(y,Fs);
isa(gongSound,'handle')

要确定变量是否为有效的句柄对象,请使用 isaisvalid

if isa(gongSound,'handle') && isvalid(gongSound)
   ...
end

删除的句柄对象

删除句柄对象后,引用该对象的句柄变量仍可存在。这些变量将不再有效,因为它们所引用的对象已不再存在。对对象调用 delete 会删除对象,但不会清除句柄变量。

例如,创建一个 audioplayer 对象:

load gong Fs y
gongSound = audioplayer(y,Fs);

输出参数 gongSound 是一个句柄变量。调用 delete 删除该对象及其包含的音频源信息:

delete(gongSound)

但是,句柄变量仍然存在:

disp(gongSound)
handle to deleted audioplayer

whos 命令将 gongSound 显示为一个 audioplayer 对象:

whos
  Name               Size             Bytes  Class          Attributes

  Fs                 1x1                  8  double                   
  gongSound          1x1                  0  audioplayer              
  y              42028x1             336224  double      

注意

whos 命令返回的字节值不包括句柄引用的数据,因为许多变量可以引用相同的数据。

句柄 gongSound 不再引用有效对象,如 isvalid 句柄方法所示:

isvalid(gongSound)
ans =

  logical

   0

对已删除的句柄调用 delete 不起任何作用,也不会导致错误。您可以将同时包含有效和无效句柄的数组传递给 delete。MATLAB 会删除有效句柄,但遇到已无效的句柄时不会生成错误。

您不能通过无效的句柄变量来访问属性:

gongSound.SampleRate
Invalid or deleted object.

访问对象属性的函数和方法会导致错误:

play(gongSound)
Invalid or deleted object.

要删除变量 gongSound,请使用 clear

clear gongSound
whos
  Name          Size             Bytes  Class     Attributes

  Fs            1x1                  8  double              
  y         42028x1             336224  double   

相关主题