我对Tobject还是不理解,:((50分)

  • 主题发起人 主题发起人 jobsxy
  • 开始时间 开始时间
J

jobsxy

Unregistered / Unconfirmed
GUEST, unregistred user!
以下代码可以正确执行:
procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
combobox1.Clear;
s := '01';
combobox1.Items.AddObject('北京',TObject(s));
s := '02';
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
edit1.Text := string(combobox1.Items.Objects[combobox1.ItemIndex]);
end;

而以下代码却不能正确执行,是什么原因呢?

procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
combobox1.Clear;
with table1 do begin
s := fieldsbyname('id').asstring;
combobox1.Items.AddObject(fieldbyname('name').asstring, TObject(s));
end;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
edit1.Text := string(combobox1.Items.Objects[combobox1.ItemIndex]);
end;
 
s := fieldsbyname('id').asstring;

s := fieldbyname('id').asstring;
没错,调试通过。此处的TObject只是进行类型转换。
 
to charlie chen:程序可以正确执行,但结果却不是我要的。
即:
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
edit1.Text := string(combobox1.Items.Objects[combobox1.ItemIndex]);
end;
这个事件执行后,edit1.text出现乱七八糟的东西,不是我需要的指定地区编码。
 
必须遍历表中数据,取出后放入组合列表框
 
我当然是遍历了全部数据。
我是要把地区名以及编码都写到Combobox里面,这样当操作员选择出地区后,我就可以
轻易地取出地区编码,就用不着以Combobox1.text为条件再到表里进行查询编码了。
 
TObject需要Create 才行。
另外,combobox1.Items.AddObject这个方法只是存放了一个指向TObject的指针
在这里是你强制转化为TObject 的 字符串S
所以,实际上Combobox中的每一项都指向同一个S
而这个S是在过程中定义的变量,在离开这个过程后内存就会被释放,
里面存放的内容是不是还在可要看操作系统高兴不高兴了。所以,你看到了一堆乱码。

正确的方法是:
建一个自己的类,带一个字符型的属性。
Type
TMyObject = class(TObject)
public
S : string[40];
end;

procedure TForm1.Button1Click(Sender: TObject);
var MyObj : TMyObject;
begin
combobox1.Clear
//如果用了AddObject,应该对每一个Item对应的Object 用Free. (我的估计,不然会造成对象释放不完全)
with table1 do begin
MyObj := TMyObject.Create;
MyObj.S := fieldsbyname('id').asstring;
combobox1.Items.AddObject(fieldbyname('name').asstring, MyObj);
end;
end;

显示时用
edit1.Text := TMyObject(combobox1.Items.Objects[combobox1.ItemIndex]).S;

OK?

 
procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
combobox1.Clear;
with table1 do begin
s := fieldsbyname('id').asstring;
[red]caption := s;//如果这里的s正确而取出来的不正确,那就是delphi的bug了[/red]
combobox1.Items.AddObject(fieldbyname('name').asstring, TObject(s));
end;
end;
 
同意lighttop,可以这么用,

type
PstrRec = ^TMystrRec;
TMystrRec = record
str : string;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
s1 : PstrRec;
begin
[blue]new(s1);[/blue] //这步是关键,效果和TObject Create一样.
combobox1.Clear;
with adotable1 do begin
s := fieldbyname('产量1').asstring;
s1.str := s;
combobox1.Items.AddObject(fieldbyname('姓名').asstring, TObject(s1));
end;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
edit2.Text := PstrRec(combobox1.Items.Objects[combobox1.ItemIndex])^.str;
edit3.Text := (combobox1.Items[combobox1.ItemIndex]);
end;

end.

不过如果我如下这么用是没问题的,有什么区别,能不能请lighttop讲课呢,鼓掌.
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
begin
combobox1.Clear;
with adotable1 do begin
s := '23';
combobox1.Items.AddObject(fieldbyname('姓名').asstring, TObject(s));
end;
end;
 
To: bluerain
依我愚见,可能跟Delphi 的优化编译有关。
因为AddObject 方法实际是保存了一个指针,而这个指针指向的是什么东西Delphi是不关心的。
实质上,指针当然是指向一个内存区域。在你的例子里,是指向一个局部变量S
我们知道,局部变量一旦离开定义它的“上下文”(你的例子里也这就procedure TForm1.Button1Click(Sender: TObject)这个过程)
它占用的内存空间就会被释放。如果你在过程中记下了这个局部变量的地址,然后在过程外访问这个地址空间的内容
得到的很可能不是你在过程内曾经赋予的值了。
我是说“很可能”,而不是绝对。
在你的例子里,你对S 赋了一个常量值:
s := '23';
或许是因为常量,在编译时DELPHI就把局部变量S的地址空间给保护起来了,即使脱离“上下文”,
该空间仍不被释放。所以你觉得这样做是可行的了。

当然,以上是我的猜想,没有深入研究验证过。希望高手指点。
 
谢谢lighttop,另外在FORM关闭时Object会不会自动Free?
因为Object是在窗口创建时建立的;
 
以下代码可以正确执行:
procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
combobox1.Clear;
s := '01';
combobox1.Items.AddObject('北京',TObject(s));
s := '02';
end;//S是局部变量,结束后就释放了

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
edit1.Text := string(combobox1.Items.Objects[combobox1.ItemIndex]);
//这里或许可以取到S,那可能因为内存虽然释放,但并没被覆盖
end;
换PChar用吧,
另:你身边没高手指导你吗,你的基本概念太弱了
 
to jobsxy:
我的理解是:如果是我们手工建立的Object , 在不需要它时应该及时Free它,以节省资源。
当然,有些对象有引用计数功能,在引用计数为零时会自动释放掉。
保险起见,还是Free一下吧。[:)]
你如果不放心,可以找一些工具软件,如BoundCheck ,查查程序结束后有没有内存泄漏。
 
多人接受答案了。
 
后退
顶部