Autor Beitrag
Jakob Schöttl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: So 08.04.07 14:02 
Hallo mal wieder,

Ich habe eine Klasse, die eine Eigenschaft besitzt vom TEdit. Eine Instanz von TEdit soll von anderen Programmteilen erstellt und zugewiesen werden. Das bedeutet, dass auch andere Programmteile das Objekt freigeben können -> Exception!

Aber was ist, wenn jetzt meine Klasse auf das Edit zugreift, obwohl gar keine Instanz von TEdit existiert?
Bis jetzt hab ich es so gemacht:
ausblenden Delphi-Quelltext
1:
if Assigned(Self.Edit) then Self.Edit.Text := 'Test';					

Aber das reicht leider nicht, weil wenn ich Self.Edit.Free aufrufe, dann zeigt Self.Editimmer noch auf ein Objekt, das aber nicht mehr existiert.
Folge: Zugriffsverletzung.

Gibt es eine Funktion, die mir sagt, ob der Objektzeiger zugewiesen ist und das Objekt existiert?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 08.04.07 14:12 
Deshalb benutzt man zum Freigeben auch die Funktion FreeAndNil(Self.Edit);

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: So 08.04.07 14:15 
ausserdem sollte man sich, wenn man Komponenten schreibt, die sich andere Komponenten zuweisen lassen, eine Methode implementieren, die Notification heisst, dort einfach schaun, ob Operation = opRemove ist, dann testen, ob AComponent dein Edit ist und wenn ja, dann kannst deinen internen zeiger auf nil setzen, weil das edit gleich ins nirvana geschickt wird

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: So 08.04.07 15:01 
mh, dann kann ich wohl nichts anderes machen, als auf Exceptionen zu reagieren.

In meinem Fall ist die Klasse ein Thread, es sieht so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
//...
type
  TLeseThread = class(TThread)
  private
    FSerial: TSerial;
  protected
    procedure Execute; override;
  public
    property Serial: TSerial read FSerial write FSerial;    
  end;

implementation

{ TLeseThread }

procedure TLeseThread.Execute;
var chr: char;
begin
  While not Terminated do  
    if Assigned(FSerial) then
      if FSerial.TryReadChar(chr) then
      begin
      end;
end;

end.


Komischerweise gibt es gar nicht gleich eine Exception, wenn ich von einer anderen Unit aus mit LesenThread.Serial.Free das Objekt freigebe, obwohl in Execute dieses Objekt die ganze Zeit genutzt wird...
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 08.04.07 15:40 
Hat jemand mal n paar Steine und ne Peitsche, um den Autor dieses Sources zu St\Peinigen?

OBJEKT-PROPERTIES NIE ÜBER DIREKTE FELDZUGRIFFE!!!

Erzeuge für deine Komponente für diese Eigenschaft separate Getter und Setter-Methoden, dann kannst Du auch entsprechend drauf reagieren...

Ferner:

KOMPONENTEN AUF DIE EIN OBJEKT ANGEWIESEN IST, NIEMALS!!! DURCH FREMDOBJEKTE FREIGEBEN!!!

Wenn Du ein Unlink vornehmen willst, dann:
ausblenden Delphi-Quelltext
1:
2:
3:
Serial := ThreadKompo.Serial;
ThreadKompo.Serial := nil;
FreeAndNil(Serial);

Dann funktioniert nämlich auch das Freigeben problemlos!!!

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: So 08.04.07 15:58 
user profile iconBenBE hat folgendes geschrieben:
Hat jemand mal n paar Steine und ne Peitsche, um den Autor dieses Sources zu St\Peinigen?

...Dass du immer gleich so brutal werden musst! :shock:

Nur könntest du vielleicht zur Verdeutlichung (Damit sogar ich es verstehe :roll: ) ein kleinens Sourcebeispiel hierzu bringen?


user profile iconBenBE hat folgendes geschrieben:
OBJEKT-PROPERTIES NIE ÜBER DIREKTE FELDZUGRIFFE!!!

Erzeuge für deine Komponente für diese Eigenschaft separate Getter und Setter-Methoden, dann kannst Du auch entsprechend drauf reagieren...

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 08.04.07 16:33 
user profile iconJayEff hat folgendes geschrieben:
Nur könntest du vielleicht zur Verdeutlichung (Damit sogar ich es verstehe :roll: ) ein kleinens Sourcebeispiel hierzu bringen?

user profile iconBenBE hat folgendes geschrieben:
OBJEKT-PROPERTIES NIE ÜBER DIREKTE FELDZUGRIFFE!!!

Erzeuge für deine Komponente für diese Eigenschaft separate Getter und Setter-Methoden, dann kannst Du auch entsprechend drauf reagieren...

Darf ich F1 sagen?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
Type
    TThreadEx = class(TThread)
    Private
        {...}
        FSerial: TSerial;
        {...}
        function GetSerial: TSerial;
        procedure SetSerial(Const Value: TSerial);
        {...}
    Public
        {...}
        property Serial: TSerial Read GetSerial write SetSerial;
        {...}
    end;

{...}

procedure TThreadEx.SetSerial(Const Value: TSerial);
Begin
    If Not Assigned(Value) Then
    Begin
        //Finish the work with the Serial ...
    end;
    FSerial := Value;
end;

Function TThreadEx.GetSerial: TSerial;
begin
    Result := FSerial;
end;


Der Getter sieht zwar erstmal sinnlos aus, verhindert aber den direkten Zugriff auf die Variable FSerial, wodurch unbefugte Manipulationen wie diese für TApplication.Mainform möglich sind, verhindert werden (und damit die Nutzung des Setters erzwungen wird.

Edit: Innerhalb der Komponente sollten nur Create und Destroy außer den beiden Setter\Getter-Methoden direkt auf die Variable FSerial zugreifen. Jeglicher andere Source sollte Serial (das Property) nutzen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: So 08.04.07 19:28 
Kannst du mir mal ein Stichwort für F1 geben, bitte? Dann kann ichs mir da nochmal anschauen.

Aber der Code sieht schon mal ganz nützlich aus - Danke!

Bloß ein Problem: Das Objekt muss in anderen Units verwendet werden! Dazu benutze ich natürlich einen anderen Zeiger. Es muss deswegen woanders verwendet werden, weil dieser Thread für das dauernde Lesen von RS 232 zuständig ist, für das Schreiben aber nicht. Und zwei Objekte von TSerial kann ich nicht verwenden, sonst ist kein Zugriff von beiden auf die Schnittstelle möglich.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: So 08.04.07 19:32 
Mir fällt gerade ein, Ich könnte doch auch eine Thread-Methode für das Schreiben machen, oder nicht? Kann ein Thread Execute ausführen, und gleichzeitig andere Thread-Methoden aufgerufen werden. Ja, zB. Terminate
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 08.04.07 19:53 
Ja. Können sie. Ach ja: Was denkst Du, wozu der Setter eines Properties zuständig ist?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: So 08.04.07 19:54 
user profile iconBenBE hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
Function TThreadEx.GetSerial: TSerial;
begin
    Result := FSerial;
end;


Der Getter sieht zwar erstmal sinnlos aus, verhindert aber den direkten Zugriff auf die Variable FSerial, wodurch unbefugte Manipulationen wie diese für TApplication.Mainform möglich sind, verhindert werden (und damit die Nutzung des Setters erzwungen wird.


das stimmt leider nicht ganz, weil wenn ich zur SetMethode noch ShowMessage schreibe und eine Eigenschaft ändere, dann wird keine ShowMessage angezeigt.
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: So 08.04.07 20:04 
naja, wenn man eine get methode hat und doch an dem objekt von ausserhalb spielen will, dann macht mans ich einfach ne variable und weisst diese zu, dann kann man spielen, bis man schwarz wird. Ausserdem finde ich, dass das Spielen dazugehört, Delphi muss manchmal vergewaltigtw erden, damit es sich ordentlich verhält, allerdings sollte man eben auch wissen, was man macht

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw