每次通过REST API数据提供的动态(增加数据)TFDMemTable定义在运行时创建TGrid时,TGrid的性能都会降低
我正在为iOS和Android开发Firemonkey应用程序。我注意到,每次在运行时使用TFDMemTable REST API数据和结构创建TGrid时,应用程序在iOS和Android调试中的性能都会变慢 我已经应用了每次通过REST API数据提供的动态(增加数据)TFDMemTable定义在运行时创建TGrid时,TGrid的性能都会降低,api,delphi,firemonkey,tgrid,fdmemtable,Api,Delphi,Firemonkey,Tgrid,Fdmemtable,我正在为iOS和Android开发Firemonkey应用程序。我注意到,每次在运行时使用TFDMemTable REST API数据和结构创建TGrid时,应用程序在iOS和Android调试中的性能都会变慢 我已经应用了FreeAndNil(TGrid1)在反复创建TGrid之前清除TGrid 一个值得注意的事件是,每次创建TGrid时,行数都会随着固定的7列而增加,性能会变慢。通常,当我到达10行或记录时会发生这种情况 我的一个大问题是: 您认为导致性能下降的管理费用来自何方 TGrid-
FreeAndNil(TGrid1)
在反复创建TGrid之前清除TGrid
一个值得注意的事件是,每次创建TGrid时,行数都会随着固定的7列而增加,性能会变慢。通常,当我到达10行或记录时会发生这种情况
我的一个大问题是:
您认为导致性能下降的管理费用来自何方
FreeAndNil(TGrid1)代码>在其创建之前
object Form9: TForm9
Left = 0
Top = 0
Caption = 'MRE TeeGrid Runtime'#13#10
ClientHeight = 480
ClientWidth = 294
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object btn1: TButton
Align = Bottom
Position.Y = 440.000000000000000000
Size.Width = 294.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 9
Text = 'CREATE TEEGRID'
OnClick = btn1Click
end
object aniSearchProcess: TAniIndicator
Position.X = 128.000000000000000000
Position.Y = 216.000000000000000000
end
object lyt1: TLayout
Align = Client
Size.Width = 294.000000000000000000
Size.Height = 440.000000000000000000
Size.PlatformDefault = False
TabOrder = 11
end
object cur1: TFDGUIxWaitCursor
Provider = 'FMX'
Left = 32
Top = 32
end
object dvr1: TFDPhysSQLiteDriverLink
Left = 88
Top = 32
end
object con1: TFDConnection
Params.Strings = (
'DriverID=SQLite')
Connected = True
LoginPrompt = False
Left = 144
Top = 32
end
object loc1: TFDLocalSQL
Connection = con1
Active = True
Left = 200
Top = 32
end
object rsc1: TRESTClient
Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
AcceptCharset = 'utf-8, *;q=0.8'
BaseURL =
'https://me6hwinr2k.execute-api.ap-southeast-1.amazonaws.com/v0/d' +
'bqueries?item-var=9&qty=25'
Params = <>
Left = 32
Top = 112
end
object rsq1: TRESTRequest
Client = rsc1
Params = <>
Response = rsp1
SynchronizedEvents = False
Left = 32
Top = 176
end
object rsp1: TRESTResponse
ContentType = 'application/json'
Left = 32
Top = 240
end
object rsd1: TRESTResponseDataSetAdapter
Active = True
Dataset = mtb1
FieldDefs = <>
Response = rsp1
Left = 32
Top = 304
end
object mtb1: TFDMemTable
Active = True
FieldDefs = <
item
Name = 'Category'
DataType = ftWideString
Size = 255
end
item
Name = 'ID'
DataType = ftWideString
Size = 255
end
item
Name = 'Item'
DataType = ftWideString
Size = 255
end
item
Name = 'Qty'
DataType = ftWideString
Size = 255
end
item
Name = 'Container'
DataType = ftWideString
Size = 255
end
item
Name = 'Size'
DataType = ftWideString
Size = 255
end
item
Name = 'Ex temporibus dolore consequatur.'
DataType = ftWideString
Size = 255
end
item
Name = 'Et cum aut est nostrum...'
DataType = ftWideString
Size = 255
end
item
Name = 'Sequi quibusdam eum.'
DataType = ftWideString
Size = 255
end>
IndexDefs = <>
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
StoreDefs = True
Left = 32
Top = 368
end
end
坦率地说,我怀疑这里是否有人能够解决您的问题,因为其他人无法真正复制它,因为我们无法访问您的REST源。相反,我建议您回到前面的问题,关于将TTeeGrid与FDMemTable一起使用。我建议这样做的原因是,它提供了一种测试/基准测试这两个组件的方法,这两个组件是相当独立的,并且(对于其他人)不依赖于对REST源的访问。您可以使用下面这样的代码来调查报告的减速是否与重复创建/释放TTeeGrid有关(我会 如果是,请感到惊讶)
坦率地说,我怀疑这里是否有人能够解决您的问题,因为其他人无法真正复制它,因为我们无法访问您的REST源。相反,我建议您回到前面的问题,关于将TTeeGrid与FDMemTable一起使用。我建议这样做的原因是,它提供了一种测试/基准测试这两个组件的方法,这两个组件是相当独立的,并且(对于其他人)不依赖于对REST源的访问。您可以使用下面这样的代码来调查报告的减速是否与重复创建/释放TTeeGrid有关(我会 如果是,请感到惊讶)
您在这里面临的问题是,由于ARC在Delphi中的工作方式,您的
TTeeGrid
实际上并没有被破坏
为什么会这样?一旦您将父组件设置为
tgd1
component,对它的引用就会添加到lyt1
控件集合中,该集合列出了所有子组件。所以当你调用FreeAndNil(tgd1)
仅从全局变量tgd1
释放对TTeeGrid
对象的引用,但布局控件集合中的引用仍然保留。由于您的TTeeGrid
引用计数未达到零,因此对象不会被销毁
因此,与其使用:
FreeAndNil(tgd1);
您需要使用:
tgd1.DisposeOf;
tgd1 := nil;
这可以确保执行TTeeGrid
对象的析构函数,而不考虑对象引用计数,这反过来会通知版面您的TTeeGrid
对象正在被销毁,因此需要将其从版面控件集合中删除,从而允许TTeeGrid
对象引用计数达到零
事实上,您应该使用DisposeOf
在运行时销毁任何组件
我建议你阅读更多关于这个主题的文章
编辑此问题仅在使用ARC的Android和iOS等移动平台上遇到。在Windows上,您的代码可以正常工作。这可能就是为什么其他人无法重现您的问题的原因
还要注意的是,由于在Delphi10.4中删除了ARC,所以您的代码也应该可以工作。但我猜你没有使用最新版本的Delphi
您可能需要编辑问题并包括您的Delphi版本,以改进此问题,因为所使用的Delphi版本会影响问题的答案。您在这里面临的问题是,由于ARC在Delphi中的工作方式,您的
TTeeGrid
不会真正被破坏
为什么会这样?一旦您将父组件设置为
tgd1
component,对它的引用就会添加到lyt1
控件集合中,该集合列出了所有子组件。所以当你调用FreeAndNil(tgd1)
仅从全局变量tgd1
释放对TTeeGrid
对象的引用,但布局控件集合中的引用仍然保留。由于您的TTeeGrid
引用计数未达到零,因此对象不会被销毁
因此,与其使用:
FreeAndNil(tgd1);
您需要使用:
tgd1.DisposeOf;
tgd1 := nil;
这可以确保执行TTeeGrid
对象的析构函数,而不考虑对象引用计数,这反过来会通知版面您的TTeeGrid
对象正在被销毁,因此需要将其从版面控件集合中删除,从而允许TTeeGrid
对象引用计数达到零
事实上,您应该使用DisposeOf
在运行时销毁任何组件
我建议你阅读更多关于这个主题的文章
编辑此问题仅在使用ARC的Android和iOS等移动平台上遇到。在Windows上,您的代码可以正常工作。这可能就是为什么其他人无法重现您的问题的原因
还要注意的是,由于在Delphi10.4中删除了ARC,所以您的代码也应该可以工作。