delphi - 阻止客户端代码在 Delphi 中释放共享对象

标签 delphi

我已经在我的 Delphi 应用程序中实现了 FlyWeight 模式。一切都很好,一切都更快,占用更少的内存,但我担心一件事。

只要客户端代码从不在共享对象上调用 Free(),我的实现就可以工作。在享元模式中,享元工厂本身应该“维护对享元的引用”,即对共享对象的引用。

我的问题是,一旦有引用,就没有(明显的)方法可以阻止其他代码破坏对象。我可以忍受这一点,但如果我可以自由地通过这些物体而不担心意外释放,那将是一个“大胜利”。

展示一个(人为的)示例:

flyweight1:=FlyweightFactory.GetFlyweight(42); 
WriteLn('Description is '+flyweight.Description); 
flyweight1.Free;

flyweight2:=FlyweightFactory.GetFlyweight(42); 
WriteLn('Description is '+flyweight.Description); 
// Object has already been Freed!; behaviour is undefined

我考虑过重写析构函数 as shown here阻止享元对象被完全释放。在我的情况下,这不是一个选择,因为

a)我只想阻止缓存的对象被释放,而不是不属于缓存的对象。有很多遗留代码不使用缓存;他们仍然需要手动创建和释放对象。

b)我确实希望 FlyweightFactory 在最终确定期间释放对象;我同意 Warren P 的观点,即“零泄漏内存”策略是最好的。

我将引用 GoF 的 Flyweight 章节中的一句话

Sharability implies some form of reference counting or garbage collection to reclaim storage when it's no longer needed. However, neither is necessary if the number of flyweights is fixed and small. In that case, the flyweights are worth keeping around permanently.



在我的情况下,飞重是“固定的”并且(足够)小。

[更新有关我如何解决此问题的详细信息,请参阅我的答案]

最佳答案

My answerquestion you link to仍然适用。对象必须通过私有(private) bool 标志知道它们是缓存对象。然后他们可以选择在 Destroy 中不毁灭自己。和 FreeInstance .如果您想允许Free,确实没有其他选择。被称为。

要处理最终确定,您可能希望将缓存对象添加到缓存对象列表中。该对象列表可以在最终确定时释放。当然,当您浏览列表时,必须重置禁用释放的标志。

关于完成这一点,我建议你注册一个预期的内存泄漏,然后泄漏这个内存。它使代码更简单,没有什么可丢失的。一旦您的可执行文件关闭,您未释放的任何内存都将被操作系统回收。提醒一句:如果您的代码被编译成 DLL,那么如果您的 DLL 被加载、卸载、再次加载等,泄漏可能会很麻烦。

这一切都在告诉你,你正在逆流而上。您是否有可能通过更适合德尔福指导您的方式的不同解决方案来实现您的目标?

关于delphi - 阻止客户端代码在 Delphi 中释放共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5877942/

相关文章:

delphi - Delphi 菜单问题

excel - Delphi 6 - 从 Delphi 应用程序创建 Excel 图表 - 数据和图表在同一页面上

delphi - 使用 imap 仅从 Gmail 'sent items' 下载一些电子邮件 header

delphi - 如何更改默认的delphi停靠窗体标题高度?

forms - 如何从 DUnit 测试中获取事件的 TGUITestRunner?

delphi - 获取周围像素的颜色并更改它们

c# - 有没有办法将 Delphi 应用程序集成到 WPF 应用程序中?

delphi - 歌词流程(Delphi/伪代码)

delphi - TMemIniFile.Create 中德语元音变音字符异常

arrays - Delphi通过表单传递多维数组