![]() |
[ARC] Clipper Arrayübergabe hat MemoryLeaks
Hallo zusammen,
ich versucher gerade die ![]() auf Fmx und Mobile zu adaptieren. Da bekomme ich aber noch so unschöne MemoryLeaks, die man leider schlecht verifizieren kann. Soweit hatte ich diese Klasse ausgemacht, wo Arrays und ArryOfArry benutzt wird um die Child-Knoten zu speichern.
Delphi-Quellcode:
Benutzt wird es dann z.B. hier
TPolyNode = class;
TArrayOfPolyNode = array of TPolyNode; TPolyNode = class private FPath : TPath; FParent : TPolyNode; FIndex : Integer; FCount : Integer; FBuffLen : Integer; FIsOpen : Boolean; FChilds : TArrayOfPolyNode; FJoinType: TJoinType; //used by ClipperOffset only FEndType : TEndType; //used by ClipperOffset only function GetChild(Index: Integer): TPolyNode; function IsHoleNode: boolean; procedure AddChild(PolyNode: TPolyNode); function GetNextSiblingUp: TPolyNode; public function GetNext: TPolyNode; property ChildCount: Integer read FCount; property Childs[index: Integer]: TPolyNode read GetChild; property Parent: TPolyNode read FParent; property IsHole: Boolean read IsHoleNode; property IsOpen: Boolean read FIsOpen; property Contour: TPath read FPath; end; function TPolyNode.GetChild(Index: Integer): TPolyNode; begin if (Index < 0) or (Index >= FCount) then raise Exception.Create('TPolyNode range error: ' + inttostr(Index)); Result := FChilds[Index]; end; procedure TPolyNode.AddChild(PolyNode: TPolyNode); begin if FCount = FBuffLen then begin Inc(FBuffLen, 16); SetLength(FChilds, FBuffLen); end; PolyNode.FParent := self; PolyNode.FIndex := FCount; FChilds[FCount] := PolyNode; //<-- Hier vermute ich das eine Referenz übergeben wird, und nicht wieder freigegeben wird Inc(FCount); end;
Delphi-Quellcode:
procedure TClipperOffset.AddPath(const Path: TPath;
JoinType: TJoinType; EndType: TEndType); var I, J, K, HighI: Integer; NewNode: TPolyNode; ip: TIntPoint; begin HighI := Length(Path)-1; //S4: if HighI < 0 then Exit; NewNode := TPolyNode.Create; //<-- CREATE hier wird ein Node angelegt NewNode.FJoinType := JoinType; NewNode.FEndType := EndType; //strip duplicate points from path and also get index to the lowest point ... if EndType in [etClosedLine, etClosedPolygon] then while (HighI > 0) and PointsEqual(Path[0], Path[HighI]) do dec(HighI); SetLength(NewNode.FPath, HighI +1); NewNode.FPath[0] := Path[0]; J := 0; K := 0; for I := 1 to HighI do if not PointsEqual(NewNode.FPath[J], Path[I]) then begin inc(J); NewNode.FPath[J] := Path[I]; if (NewNode.FPath[K].Y < Path[I].Y) or ((NewNode.FPath[K].Y = Path[I].Y) and (NewNode.FPath[K].X > Path[I].X)) then K := J; end; inc(J); if J < HighI +1 then SetLength(NewNode.FPath, J); if (EndType = etClosedPolygon) and (J < 3) then begin NewNode.free; //<-- Hier wird etwas freigegeben Exit; end; FPolyNodes.AddChild(NewNode); //<-- hier wird der NewNode übergeben, uns sollte dann nur in den PolyNodes referenziert sein if EndType <> etClosedPolygon then Exit; //if this path's lowest pt is lower than all the others then update FLowest if (FLowest.X < 0) then begin FLowest := IntPoint(FPolyNodes.ChildCount -1, K); end else begin ip := FPolyNodes.Childs[FLowest.X].FPath[FLowest.Y]; if (NewNode.FPath[K].Y > ip.Y) or ((NewNode.FPath[K].Y = ip.Y) and (NewNode.FPath[K].X < ip.X)) then FLowest := IntPoint(FPolyNodes.ChildCount -1, K); end; end; procedure TClipperOffset.AddPaths(const Paths: TPaths; JoinType: TJoinType; EndType: TEndType); var I: Integer; begin for I := 0 to Length(Paths)-1 do AddPath(Paths[I], JoinType, EndType); end; Leider ist der Code etwas unübersichtlich und unüblich, deshalb sehe ich den Wald vor Bäumen nicht mehr. Sieht vielleicht jemand den Fehler im Bild, oder hat schon jemand diese Library portiert ? Ich brauche davon eigentlich nur die Offset/Inflate Routine des Polygons, es scheint aber das diese ClipperLibrary das einzige auf weiter Flur ist was das sauber lösen kann. Wie gesagt, es funktioniert alles Super, auch unter IOS/Android, nur das ich unter iOS(android ?) MemoryLeaks bekomme. Und Apple versteht da keinen Spass. Siehe hier: Zitat:
Rollo |
AW: [ARC] Clipper Arrayübergabe hat MemoryLeaks
Und wenn du das mal einfügst? :stupid:
Delphi-Quellcode:
TPolyNode = class
private FPath : TPath; [weak] // prevents ARC circular reference FParent : TPolyNode; FIndex : Integer; FCount : Integer; ... |
AW: [ARC] Clipper Arrayübergabe hat MemoryLeaks
Hallo Sir Rufo,
danksehr, sowas hatte ich mir schon gedacht. Bin mit nur nicht sicher ob zuviel [Weak] nicht auch schaden kann. Insbesondere bei so einem Spagetticode. Gibt es da eine Faustregel, wann sollte man es NICHT anwenden ? Kann man Weak Referenzen genau wie bisher Create/Free machen, ohne das etwas in die Hose geht ? Werds jedenfalls gleich mal Testen. EDIT: Ja, du hast wie immer Recht. Dann kann ich ja für heute den Deckel zuklappen. Über die negativen Seiten von Weak mache ich mir dann morgen Gedanken :-) Rollo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz