<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Objetos com contagem de referência</title>
	<atom:link href="http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html</link>
	<description>Object Pascal e ferramentas de programação com Arte</description>
	<pubDate>Sun, 05 Feb 2012 04:22:36 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
		<item>
		<title>By: Jennifer-Tool</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-23748</link>
		<dc:creator>Jennifer-Tool</dc:creator>
		<pubDate>Fri, 23 Oct 2009 09:15:42 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-23748</guid>
		<description>bom comeco</description>
		<content:encoded><![CDATA[<p>bom comeco</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Silvio Clécio</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-14389</link>
		<dc:creator>Silvio Clécio</dc:creator>
		<pubDate>Mon, 23 Mar 2009 20:16:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-14389</guid>
		<description>Oops,

{...}
depois em “function FreeInstance;”, troco por “procedure FreeInstance; override;”
{...}

O original tb tem override, ficando assim: "function FreeInstance; override", mas, só compila quando mudo para procedure.</description>
		<content:encoded><![CDATA[<p>Oops,</p>
<p>{&#8230;}<br />
depois em “function FreeInstance;”, troco por “procedure FreeInstance; override;”<br />
{&#8230;}</p>
<p>O original tb tem override, ficando assim: &#8220;function FreeInstance; override&#8221;, mas, só compila quando mudo para procedure.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Silvio Clécio</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-14387</link>
		<dc:creator>Silvio Clécio</dc:creator>
		<pubDate>Mon, 23 Mar 2009 20:12:48 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-14387</guid>
		<description>Olá João,

Veja o source de um teste simples:

---
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TRefCountObject = class(TObject)
  private
    FRefCount: Integer;
    function Release;
  protected
    procedure Finit; virtual;
  public
    destructor Destroy; reintroduce;
    function AddRef;
    function FreeInstance; override;
    class function NewInstance: TObject; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TRefCountObject.AddRef;
begin
  Result := InterlockedIncrement(FRefCount);
end;

destructor TRefCountObject.Destroy;
begin
end;

function TRefCountObject.Finit;
begin
end;

function TRefCountObject.FreeInstance;
begin
  if Release = 0 then
    try
      Finit;
    finally
      inherited;
    end;
end;

class function TRefCountObject.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  TRefCountObject(Result).FRefCount := 1;
end;

function TRefCountObject.Release;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result &#60; 0 then
    raise Exception.Create('Não é possível liberar a instância');
end;

end.
---

Primeiro o compilador esbarra na linha "function Release;", troco por "function Release: Integer; stdcall;" e passa, depois em "function AddRef;", troco por "function AddRef: Integer; stdcall;" e passa, depois em "function FreeInstance;", troco por "procedure FreeInstance; override;" e passa.

Note que teve houve umas mudanças, de function para procedure, e outras coisas (ex: ": Integer; stdcall").

Eu uso Delphi7, será que estou fazendo algo errado?

Depois que deixei assim não deu mais erros:
---
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TRefCountObject = class(TObject)
  private
    FRefCount: Integer;
    function Release: Integer; stdcall;
  protected
    procedure Finit; virtual;
  public
    destructor Destroy; reintroduce;
    function AddRef: Integer; stdcall;
    procedure FreeInstance; override;
    class function NewInstance: TObject; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TRefCountObject.AddRef;
begin
  Result := InterlockedIncrement(FRefCount);
end;

destructor TRefCountObject.Destroy;
begin
end;

procedure TRefCountObject.Finit;
begin
end;

procedure TRefCountObject.FreeInstance;
begin
  if Release = 0 then
    try
      Finit;
    finally
      inherited;
    end;
end;

class function TRefCountObject.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  TRefCountObject(Result).FRefCount := 1;
end;

function TRefCountObject.Release;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result &#60; 0 then
    raise Exception.Create('Não é possível liberar a instância');
end;

end.
---

P.S.: João, tem como notificar quando os comentários forem respondidos? Eu tenho muito interesse nas postagens que você faz, elas valem mais que alguns livros sobre ObjectPascal (a maioria mostrando no Delphi) que estão aí no mercado.

Um grande abraço!
Silvio Clécio</description>
		<content:encoded><![CDATA[<p>Olá João,</p>
<p>Veja o source de um teste simples:</p>
<p>&#8212;<br />
unit Unit1;</p>
<p>interface</p>
<p>uses<br />
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br />
  Dialogs;</p>
<p>type<br />
  TForm1 = class(TForm)<br />
  private<br />
    { Private declarations }<br />
  public<br />
    { Public declarations }<br />
  end;</p>
<p>  TRefCountObject = class(TObject)<br />
  private<br />
    FRefCount: Integer;<br />
    function Release;<br />
  protected<br />
    procedure Finit; virtual;<br />
  public<br />
    destructor Destroy; reintroduce;<br />
    function AddRef;<br />
    function FreeInstance; override;<br />
    class function NewInstance: TObject; override;<br />
  end;</p>
<p>var<br />
  Form1: TForm1;</p>
<p>implementation</p>
<p>{$R *.dfm}</p>
<p>function TRefCountObject.AddRef;<br />
begin<br />
  Result := InterlockedIncrement(FRefCount);<br />
end;</p>
<p>destructor TRefCountObject.Destroy;<br />
begin<br />
end;</p>
<p>function TRefCountObject.Finit;<br />
begin<br />
end;</p>
<p>function TRefCountObject.FreeInstance;<br />
begin<br />
  if Release = 0 then<br />
    try<br />
      Finit;<br />
    finally<br />
      inherited;<br />
    end;<br />
end;</p>
<p>class function TRefCountObject.NewInstance: TObject;<br />
begin<br />
  Result := inherited NewInstance;<br />
  TRefCountObject(Result).FRefCount := 1;<br />
end;</p>
<p>function TRefCountObject.Release;<br />
begin<br />
  Result := InterlockedDecrement(FRefCount);<br />
  if Result &lt; 0 then<br />
    raise Exception.Create(&#8217;Não é possível liberar a instância&#8217;);<br />
end;</p>
<p>end.<br />
&#8212;</p>
<p>Primeiro o compilador esbarra na linha &#8220;function Release;&#8221;, troco por &#8220;function Release: Integer; stdcall;&#8221; e passa, depois em &#8220;function AddRef;&#8221;, troco por &#8220;function AddRef: Integer; stdcall;&#8221; e passa, depois em &#8220;function FreeInstance;&#8221;, troco por &#8220;procedure FreeInstance; override;&#8221; e passa.</p>
<p>Note que teve houve umas mudanças, de function para procedure, e outras coisas (ex: &#8220;: Integer; stdcall&#8221;).</p>
<p>Eu uso Delphi7, será que estou fazendo algo errado?</p>
<p>Depois que deixei assim não deu mais erros:<br />
&#8212;<br />
unit Unit1;</p>
<p>interface</p>
<p>uses<br />
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br />
  Dialogs;</p>
<p>type<br />
  TForm1 = class(TForm)<br />
  private<br />
    { Private declarations }<br />
  public<br />
    { Public declarations }<br />
  end;</p>
<p>  TRefCountObject = class(TObject)<br />
  private<br />
    FRefCount: Integer;<br />
    function Release: Integer; stdcall;<br />
  protected<br />
    procedure Finit; virtual;<br />
  public<br />
    destructor Destroy; reintroduce;<br />
    function AddRef: Integer; stdcall;<br />
    procedure FreeInstance; override;<br />
    class function NewInstance: TObject; override;<br />
  end;</p>
<p>var<br />
  Form1: TForm1;</p>
<p>implementation</p>
<p>{$R *.dfm}</p>
<p>function TRefCountObject.AddRef;<br />
begin<br />
  Result := InterlockedIncrement(FRefCount);<br />
end;</p>
<p>destructor TRefCountObject.Destroy;<br />
begin<br />
end;</p>
<p>procedure TRefCountObject.Finit;<br />
begin<br />
end;</p>
<p>procedure TRefCountObject.FreeInstance;<br />
begin<br />
  if Release = 0 then<br />
    try<br />
      Finit;<br />
    finally<br />
      inherited;<br />
    end;<br />
end;</p>
<p>class function TRefCountObject.NewInstance: TObject;<br />
begin<br />
  Result := inherited NewInstance;<br />
  TRefCountObject(Result).FRefCount := 1;<br />
end;</p>
<p>function TRefCountObject.Release;<br />
begin<br />
  Result := InterlockedDecrement(FRefCount);<br />
  if Result &lt; 0 then<br />
    raise Exception.Create(&#8217;Não é possível liberar a instância&#8217;);<br />
end;</p>
<p>end.<br />
&#8212;</p>
<p>P.S.: João, tem como notificar quando os comentários forem respondidos? Eu tenho muito interesse nas postagens que você faz, elas valem mais que alguns livros sobre ObjectPascal (a maioria mostrando no Delphi) que estão aí no mercado.</p>
<p>Um grande abraço!<br />
Silvio Clécio</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joao Morais</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-14305</link>
		<dc:creator>Joao Morais</dc:creator>
		<pubDate>Sat, 21 Mar 2009 03:04:51 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-14305</guid>
		<description>Olá Silvio, qual a diferença (além do stdcall) e qual o problema que impediu você de compilar e usar o seu código?</description>
		<content:encoded><![CDATA[<p>Olá Silvio, qual a diferença (além do stdcall) e qual o problema que impediu você de compilar e usar o seu código?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Silvio Clécio</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-14268</link>
		<dc:creator>Silvio Clécio</dc:creator>
		<pubDate>Fri, 20 Mar 2009 07:07:29 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-14268</guid>
		<description>Olá João,

Posso estar errado, mas, não seria assim:

---
type
  TRefCountObject = class(TObject)
  private
    FRefCount: Integer;
    function Release: Integer; stdcall;
  protected
    procedure Finit; virtual;
  public
    destructor Destroy; reintroduce;
    function AddRef: Integer; stdcall;
    procedure FreeInstance; override;
    class function NewInstance: TObject; override;
  end;
---

implementation

function TRefCountObject.AddRef;
begin
  Result := InterlockedIncrement(FRefCount);
end;

destructor TRefCountObject.Destroy;
begin
end;

procedure TRefCountObject.Finit;
begin
end;

procedure TRefCountObject.FreeInstance;
begin
  if Release = 0 then
    try
      Finit;
    finally
      inherited;
    end;
end;

class function TRefCountObject.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  TRefCountObject(Result).FRefCount := 1;
end;

function TRefCountObject.Release;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result &#60; 0 then
    raise Exception.Create('Não é possível liberar a instância');
end;
---


Só assim consegui fazer:

---
TCliente = class(TRefCountObject)
...
end;
---
procedure GuardaCliente(const ACliente: TCliente);
begin
  FCliente := ACliente;
  FCliente.AddRef;
end;
---

Um grande abraço,
Silvio Clécio</description>
		<content:encoded><![CDATA[<p>Olá João,</p>
<p>Posso estar errado, mas, não seria assim:</p>
<p>&#8212;<br />
type<br />
  TRefCountObject = class(TObject)<br />
  private<br />
    FRefCount: Integer;<br />
    function Release: Integer; stdcall;<br />
  protected<br />
    procedure Finit; virtual;<br />
  public<br />
    destructor Destroy; reintroduce;<br />
    function AddRef: Integer; stdcall;<br />
    procedure FreeInstance; override;<br />
    class function NewInstance: TObject; override;<br />
  end;<br />
&#8212;</p>
<p>implementation</p>
<p>function TRefCountObject.AddRef;<br />
begin<br />
  Result := InterlockedIncrement(FRefCount);<br />
end;</p>
<p>destructor TRefCountObject.Destroy;<br />
begin<br />
end;</p>
<p>procedure TRefCountObject.Finit;<br />
begin<br />
end;</p>
<p>procedure TRefCountObject.FreeInstance;<br />
begin<br />
  if Release = 0 then<br />
    try<br />
      Finit;<br />
    finally<br />
      inherited;<br />
    end;<br />
end;</p>
<p>class function TRefCountObject.NewInstance: TObject;<br />
begin<br />
  Result := inherited NewInstance;<br />
  TRefCountObject(Result).FRefCount := 1;<br />
end;</p>
<p>function TRefCountObject.Release;<br />
begin<br />
  Result := InterlockedDecrement(FRefCount);<br />
  if Result &lt; 0 then<br />
    raise Exception.Create(&#8217;Não é possível liberar a instância&#8217;);<br />
end;<br />
&#8212;</p>
<p>Só assim consegui fazer:</p>
<p>&#8212;<br />
TCliente = class(TRefCountObject)<br />
&#8230;<br />
end;<br />
&#8212;<br />
procedure GuardaCliente(const ACliente: TCliente);<br />
begin<br />
  FCliente := ACliente;<br />
  FCliente.AddRef;<br />
end;<br />
&#8212;</p>
<p>Um grande abraço,<br />
Silvio Clécio</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joao Morais</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-3267</link>
		<dc:creator>Joao Morais</dc:creator>
		<pubDate>Wed, 03 Dec 2008 15:34:48 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-3267</guid>
		<description>Não exatamente. Da forma que você propôs eu tenho que usar interfaces para ter contagem de referência. Isto TInterfacedObject já faz. A minha proposta é você usar contagem de referência com objetos, e continuar gerenciando a memória da mesma forma de sempre (com .Free)

Então posso ter código desta forma:

begin
  VCliente := TCliente.Create;
  try
    GuardaCliente(VCliente);
  finally
    VCliente.Free;
  end;
end;

procedure GuardaCliente(const ACliente: TCliente);
begin
  FCliente := ACliente;
  FCliente.AddRef;
end;

E depois da chamada a VCliente.Free, o objeto continuará na memória para atender o ponteiro FCliente.</description>
		<content:encoded><![CDATA[<p>Não exatamente. Da forma que você propôs eu tenho que usar interfaces para ter contagem de referência. Isto TInterfacedObject já faz. A minha proposta é você usar contagem de referência com objetos, e continuar gerenciando a memória da mesma forma de sempre (com .Free)</p>
<p>Então posso ter código desta forma:</p>
<p>begin<br />
  VCliente := TCliente.Create;<br />
  try<br />
    GuardaCliente(VCliente);<br />
  finally<br />
    VCliente.Free;<br />
  end;<br />
end;</p>
<p>procedure GuardaCliente(const ACliente: TCliente);<br />
begin<br />
  FCliente := ACliente;<br />
  FCliente.AddRef;<br />
end;</p>
<p>E depois da chamada a VCliente.Free, o objeto continuará na memória para atender o ponteiro FCliente.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marcos George</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-3265</link>
		<dc:creator>Marcos George</dc:creator>
		<pubDate>Wed, 03 Dec 2008 15:02:39 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-3265</guid>
		<description>Se eu entendi bem, o que vc propõe é o que o XmlDocument faz: quando usado como componente, não usa o mecanismo de reference counting, mas quando usado através da interface IXmlDocument, usa reference counting. É isso?

Eu uso um híbrido de OO/RAD nos meus aplicativos antigos: Criei um datamodule cujo nome é o nome da classe (ex.: Cliente). O datamodule contém um clientdataset que faz o acesso aos dados no DB. Ao mesmo tempo, o DM implementa uma interface (digamos, ICliente) e para que ele trabalhe com reference counting eu implementei algo parecido. Assim, eu posso fazer:

var
  Cliente: ICliente;
begin
  Cliente := ClienteFactory.CriarCliente;
  Cliente.ConsultarPeloCodigo('0001');
  ShowMessage(Cliente.Nome)
end;

Mas quando usado como componente eu tenho que destruí-lo manualmente:

var
  Cliente: TCliente;
begin
  Cliente := TCliente.Create(nil, Connection)
  try
    Cliente.ConsultarPeloCodigo('0001');
    ShowMessage(Cliente.Nome);
  finally
    Cliente.Free;
  end;
end;

Assim, eu mantenho o comportamento padrão de um datamodule (sem ref. Counting) e ao mesmo tempo, quando desejado, posso usar o Ref. Counting.

Um abraço. Legal o seu blog.

:)</description>
		<content:encoded><![CDATA[<p>Se eu entendi bem, o que vc propõe é o que o XmlDocument faz: quando usado como componente, não usa o mecanismo de reference counting, mas quando usado através da interface IXmlDocument, usa reference counting. É isso?</p>
<p>Eu uso um híbrido de OO/RAD nos meus aplicativos antigos: Criei um datamodule cujo nome é o nome da classe (ex.: Cliente). O datamodule contém um clientdataset que faz o acesso aos dados no DB. Ao mesmo tempo, o DM implementa uma interface (digamos, ICliente) e para que ele trabalhe com reference counting eu implementei algo parecido. Assim, eu posso fazer:</p>
<p>var<br />
  Cliente: ICliente;<br />
begin<br />
  Cliente := ClienteFactory.CriarCliente;<br />
  Cliente.ConsultarPeloCodigo(&#8217;0001&#8242;);<br />
  ShowMessage(Cliente.Nome)<br />
end;</p>
<p>Mas quando usado como componente eu tenho que destruí-lo manualmente:</p>
<p>var<br />
  Cliente: TCliente;<br />
begin<br />
  Cliente := TCliente.Create(nil, Connection)<br />
  try<br />
    Cliente.ConsultarPeloCodigo(&#8217;0001&#8242;);<br />
    ShowMessage(Cliente.Nome);<br />
  finally<br />
    Cliente.Free;<br />
  end;<br />
end;</p>
<p>Assim, eu mantenho o comportamento padrão de um datamodule (sem ref. Counting) e ao mesmo tempo, quando desejado, posso usar o Ref. Counting.</p>
<p>Um abraço. Legal o seu blog.</p>
<p> <img src='http://blog.joaomorais.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: auta ze szwecji</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-2865</link>
		<dc:creator>auta ze szwecji</dc:creator>
		<pubDate>Wed, 19 Nov 2008 21:46:39 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-2865</guid>
		<description>Very interesting article, i bookmarked your blog
Best regards</description>
		<content:encoded><![CDATA[<p>Very interesting article, i bookmarked your blog<br />
Best regards</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rodrigo Palhano</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-1839</link>
		<dc:creator>Rodrigo Palhano</dc:creator>
		<pubDate>Wed, 08 Oct 2008 11:47:52 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-1839</guid>
		<description>Saquei.</description>
		<content:encoded><![CDATA[<p>Saquei.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joao Morais</title>
		<link>http://blog.joaomorais.com.br/2008/09/06/objetos-contagem-ref.html#comment-1836</link>
		<dc:creator>Joao Morais</dc:creator>
		<pubDate>Wed, 08 Oct 2008 11:11:32 +0000</pubDate>
		<guid isPermaLink="false">http://blog.joaomorais.com.br/?p=81#comment-1836</guid>
		<description>Não. Você não pode chamar .Free de um decendente de TInterfacedObject. A proposta é trabalhar com contagem de referência sem alterar a usabilidade do gerenciamento de memória do TObject.</description>
		<content:encoded><![CDATA[<p>Não. Você não pode chamar .Free de um decendente de TInterfacedObject. A proposta é trabalhar com contagem de referência sem alterar a usabilidade do gerenciamento de memória do TObject.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

