Was ist ein iStream Wrapper?
Interface-Typen können sich selbst freigeben.
Deswegen denke ich das sowas dir helfen könnte...
Delphi-Quellcode:
type
IMemoryStream =
interface
Function GetStream:TMemoryStream;
procedure SetStream(aValue:TMemoryStream);
end;
TStreamWrapper=Class(TInterfacedObject, IMemoryStream )
private
fStream:TMemoryStream
Public
Function GetStream:TMemoryStream;
procedure SetStream(aValue:TMemoryStream);
// Hier könnte man noch alle Stream Methoden hinpaken die man selbst oft benutzt
// die wrappen quasi die methoden vom TMemoyStream, weil sie einfach nur die selbe Methode in FStream aufrufen.
Constructor Create;
Virtual;
Destructor Destroy;
Override;
Property Stream:TMemoryStream
read GetStream
write SetStream;
end;
Implementation
Function TStreamWrapper.SetStream(aValue:TMemoryStream);
Begin
if Assigned(fStream)
then
FreeAndNil(fStream);
// ODER Raise Exception.create('Fehler der Wrapper besitzt bereits einen Stream!');
fStream := aValue;
end;
Function TStreamWrapper.GetStream:TMemoryStream;
Begin
Result := fStream
end;
Constructor TStreamWrapper.Create;
Begin
inherited;
fStream :=
nil;
end;
Destructor TStreamWrapper.Destroy;
Begin
if Assigned(fStream)
then
FreeAndNil(fStream);
inherited;
end;
Statt Streams als Rückgabewert von Funktionen solltest du den Wrapper ausgeben.
Der Wrapper würde den Stream Freigeben wenn keine Variable mehr den Wrapper referenziert. Daher kommt es nicht mehr zu Speicherlecks wenn du den Stream nicht freigibst.
Mann nennt das ARC...RC steht für Referenzählung...
Wichtig ist das NUR der Wrapper den Stream kennt. Sonnst kommt es zwar nicht so Speicherlecks aber zu "use after free" Fehlern.
Man benutzt es so dass man nur IMemorystream referenziert!
Delphi-Quellcode:
var LStream:IMemoryStream := (TStreamWrapper.create as IMemoryStream );
LStream.Stream := TMemoryStream.create;