我有两个类(在我的示例中为TObject1和TObject2),它们通过接口(IObject1,IObject2)相互了解.正如您在Delphi中可能知道的那样,这将导致内存泄漏,因为参考计数器将始终保持在零以上.通常的解决方案是将一个引用声明为弱.这在大多数情况下都适用,因为你通常知道哪一个会被破坏,或者一旦它被销毁就不一定需要弱引用后面的对象.
这说我尝试以这样的方式解决问题,即两个对象都保持活着,直到两者都不再被引用:(因为我使用[unsafe]属性需要Delphi 10.1)
program Project14;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
IObject2 = interface;
IObject1 = interface
['{F68D7631-4838-4E15-871A-BD2EAF16CC49}']
function GetObject2: IObject2;
end;
IObject2 = interface
['{98EB60DA-646D-4ECF-B5A7-6A27B3106689}']
end;
TObject1 = class(TInterfacedObject, IObject1)
[unsafe] FObj2: IObject2;
constructor Create;
destructor Destroy; override;
function GetObject2: IObject2;
end;
TObject2 = class(TContainedObject, IObject2)
[unsafe] FObj1: IObject1;
constructor Create(aObj1: IObject1);
destructor Destroy; override;
end;
constructor TObject1.Create;
begin
FObj2 := TObject2.Create(Self);
end;
destructor TObject1.Destroy;
begin
TContainedObject(FObj2).Free;
inherited Destroy;
end;
function TObject1.GetObject2: IObject2;
begin
Result := FObj2;
end;
constructor TObject2.Create(aObj1: …Run Code Online (Sandbox Code Playgroud) 一个人可以使用
http://docwiki.embarcadero.com/Libraries/Seattle/en/System.IOUtils.TPath.DirectorySeparatorChar
要么
是否有任何特殊的差异,使用System.IOUtils.Tath中的另一个部分的好处是更面向对象的接口?
http://docwiki.embarcadero.com/Libraries/Seattle/en/System.SysUtils
有没有办法从父类调用子类的创建?下面是这个Duplicate方法,我希望调用子类的构造函数,以便底部的测试成功.
type
IBla<T> = interface(IInvokable)
['{34E812BF-D021-422A-A051-A492F25534C4}']
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassA<T> = class(TInterfacedObject, IBla<T>)
protected
function GetInt(): Integer; virtual;
public
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassB = class(TClassA<Integer>, IBla<Integer>)
protected
function GetInt(): Integer; override;
end;
function TClassA<T>.Duplicate: IBla<T>;
begin
Exit(TClassA<T>.Create());
end;
function TClassA<T>.GetInt: Integer;
begin
Exit(1);
end;
function TClassA<T>.GetIntFromIface: Integer;
begin
Exit(GetInt());
end;
function TClassB.GetInt: Integer;
begin
Exit(2);
end;
procedure TestRandomStuff.Test123;
var
o1, o2: IBla<Integer>;
begin
o1 := TClassB.Create();
o2 := o1.Duplicate();
Assert.AreEqual(o2.GetIntFromIface, 2);
end;
Run Code Online (Sandbox Code Playgroud) 在C++中,可以通过const引用以这种方式将函数传递给函数:
void test(const std::vector<int>& a);
Run Code Online (Sandbox Code Playgroud)
当向量非常大并且我想避免浪费时间来复制它时,这很有用.我知道Delphi中的相同代码是:
procedure test(const [Ref] a: array of Integer);
Run Code Online (Sandbox Code Playgroud)
它是否也具有与C++相同的效果(传递地址而不是副本并优化/节省时间)?这是唯一的方法还是还有其他优化参数传递的方法?
在Delphi 10.1.2 Berlin中,在一个Vcl.Dialogs.MessageDlg函数中,DlgType常量mtInformation和mtConfirmation创建相同的对话框图标.例如:
if Vcl.Dialogs.MessageDlg('Do you really want to remove the selected item?', mtConfirmation, mbOKCancel, 0) = mrOk then
begin
RemoveTheSelectedItem;
end;
Run Code Online (Sandbox Code Playgroud)
if Vcl.Dialogs.MessageDlg('Do you really want to remove the selected item?', mtInformation, mbOKCancel, 0) = mrOk then
begin
RemoveTheSelectedItem;
end;
Run Code Online (Sandbox Code Playgroud)
但不应该DlgType常数mtConfirmation显示一个问号图标,(作为其他DlgType常量mtWarning并mtError创建每个不同的图标)?
如何使用常量获得问号图标?DlgTypemtConfirmation
我有一个Delphi 10.1 Berlin Datasnap Server,它不能返回大于260.000字节的数据包(通过TStream).
我在Delphi 的\ Object Pascal\DataSnap\FireDAC示例之后编写了它,它也显示了这个问题.
只需打开该示例,在ServerMethodsUnit.pas上将qOrders组件的IndexFieldName设置为空白,并将其SQL属性更改为:
select * from Orders
union
select * from Orders
Run Code Online (Sandbox Code Playgroud)
现在要发送的数据量超过260.000字节,这似乎是您无法从客户端检索它的点.获得EFDException [FireDAC] [Stan] -710.二进制存储格式无效.
数据作为Stream从服务器上的FDSchemaAdapter获取,然后加载到客户端上的另一个FDSchemaAdpater.客户端和服务器之间的连接也是FireDAC.
这是服务器返回该流的方式:
function TServerMethods.StreamGet: TStream;
begin
Result := TMemoryStream.Create;
try
qCustomers.Close;
qCustomers.Open;
qOrders.Close;
qOrders.Open;
FDSchemaAdapter.SaveToStream(Result, TFDStorageFormat.sfBinary);
Result.Position := 0;
except
raise;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这就是客户端检索它的方式:
procedure TClientForm.GetTables;
var
LStringStream: TStringStream;
begin
FDStoredProcGet.ExecProc;
LStringStream := TStringStream.Create(FDStoredProcGet.Params[0].asBlob);
try
if LStringStream <> nil then
begin
LStringStream.Position := 0;
DataModuleFDClient.FDSchemaAdapter.LoadFromStream(LStringStream, TFDStorageFormat.sfBinary);
end;
finally
LStringStream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
客户端无法获取Blob参数的所有数据.我在服务器上保存Stream的内容,以及在客户端上到达Blob参数的内容,并且它们具有相同的大小,但Blob参数的内容的内容被截断,最后几个Kbytes为零.
这就是我在服务器上保存将转到Stream的内容的方法:
FDSchemaAdapter.SaveToFile('C:\Temp\JSON_Server.json', TFDStorageFormat.sfJSON); …Run Code Online (Sandbox Code Playgroud) 我正在使用TDialogServiceAsync.InputQuery()单个输入进行简单的调用.它只是忽略了Cancel按钮和窗口的X关闭按钮.
但Ok按钮工作正常.
这是我的代码:
uses
FMX.DialogService.Async;
procedure TForm1.Button1Click(Sender: TObject);
begin
TDialogServiceAsync.InputQuery('Title',
['Insert value'], ['bla bla'],
procedure(const AResult: TModalResult; const AValues: array of string)
begin
if Aresult = mrOk then
ShowMessage('Ok!');
if Aresult = mrCancel then
ShowMessage('Cancel!'); // this is never called
end);
end;
Run Code Online (Sandbox Code Playgroud)
如果我按下Cancel,则InputQuery窗口不会关闭,并且不会调用我的回调过程.
按下Cancel按钮后如何关闭InputQuery表单?
我正在使用RADStudio 10.1柏林.
编辑:
我做了几个测试:
这与具有子窗体的Delphi应用程序有关,该子窗体已显示然后隐藏但未释放。如果用户将鼠标悬停在应用程序的(Windows 10)任务栏“迷你视图”上,则隐藏的窗体将变得可见(在悬停期间)。当用户单击迷你视图以将焦点更改为时,它们将隐藏。应用程序。有什么办法可以避免这种情况?
重新创建:
请注意,最小化应用程序并还原它可以“修复”影响,直到下次显示表单为止。也许这是导致问题的线索或解决方法的线索?这并不是一个大问题,因为它似乎并没有引起任何实际问题,但是看起来确实不专业。
根据要求添加代码(但是,这不会很有趣。)
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
// Only code that was added to TForm1:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Show and then hide the form or use ShowModal and close it before testing the hover.
Form2.Show;
Form2.Hide;
// Form2.ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)
更新:如何仅使用Delphi IDE显示问题。
我有一个应用程序,我捕获异常并向用户显示消息文本作为错误消息的一部分.尽管RAD Studio(10.1)设置为英语,并且在所有目标的版本信息选项中将区域设置ID设置为409英语,但错误消息以德语输出.这种情况发生在德国Windows 10和其他语言的其他Windows机器上,即使是日本客户也是如此.
例外是一个系统异常,例如无法打开文件,找不到文件,但它似乎发生在我不用我自己的消息文本引发的所有类型的异常上.
该项目最近已从Delphi 2007迁移,我不得不在项目文件中对版本号进行一些手动清理.但是检查项目文件中的Locale并不奇怪:1033 - > $ 0409 - 英语.
可能是德国消息的原因在哪里?
在VCL Forms程序中,我有一个Form,它实现了一种处理Windows消息和更新Form上某些控件的方法,如:
procedure OnMsgTest (var Msg: TMessage); message WM_CUSTOMTEST;
Run Code Online (Sandbox Code Playgroud)
我使用PostMessage自定义消息到此表单,使用如下代码:
h := FindWindow('TFrmTest', nil);
if IsWindow(h) then begin
PostMessage(h, WM_CUSTOMTEST, 0, 0);
end;
Run Code Online (Sandbox Code Playgroud)
当Form实例化多次时,使用上面的代码发送消息,只有一个Form实例更新屏幕上的信息.我希望所有打开和实例化的表单都能收到消息.
一个重要的注意事项:PostMessage可以在Form进程本身内发生,也可以从另一个进程发生.所以,我认为通过Forms的循环不起作用.
达到目标的最佳方法是什么?