TComboBox的Items属性赋值解析

一般情况下对象类型作为参数传递时,传递的类型为引用型。因此,当对传入的参数执行Free时,该对象将被从内存清除。那么所有对它的引用将失效

但最近在写TComboBox相关的赋值操作时却发现,TComboBox的Items属性为TStrings类型,但执行
combobox.items := stringlist;
之后free掉stringlist,发现TComboBox的Items并没有被free掉,而是保持了原来的数据。

因此,我们可以想到在TComboBox的Items赋值操作中有一个数据复制机制,而不是简单的将引用赋值给Items属性。

打开stdCtrls单元,找到TCustomCombo的Items定义位置(TComboBox继承自TCustomCombo,其Items属性在TCustomCombo实现),我们发现下面一条语句:

property Items: TStrings read FItems write SetItems;

嗯,果然有一个SetItems,我们一起来看一下这个函数的实现,真相大白:

procedure TCustomCombo.SetItems(const Value: TStrings);
begin
  if Assigned(FItems) then
    FItems.Assign(Value)
  else
    FItems := Value;
end;

SetItems函数使用了其父类TPersistent的Assign函数来实现数据赋值,而只有在FItems成员为nil时才会复制引用,那么TComboBox必定在创建之时创建了FItems成员

为了验证这点,因为TComboBox仅仅是将TCustomComboBox封装成标准的VCL控件,本身并没有代码实现,因此,我们找到了TComboBox的直接父类TCustomComboBox,在它的Create函数中有这么一句:

FItems := GetItemsClass.Create;

这里VCL使用了一个技巧(此技巧在VCL Framework中大量出现),用GetItemsClass返回类对象,然后用其创建对象。

由此我们可以看到,FItems确实是在TComboBox创建的时候被初始化了,因此,只要没有去显式的free它,Items属性的赋值操作均为数据复制。

到此也找到了上述看似奇怪的问题。

VCL Framework中使用了大量的技巧以保证其高度的灵活性和极高的执行效率,多多深入研究VCL的实现方法对我们的设计思想大有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值