私は、コードの他の部分もフォームに属するプロパティを介して参照を取得するインターフェイスオブジェクトの背後にある機能を提供するDelphiフォームを持っています。あまりにも多くの機能がフォーム上のコントロール/コンポーネントによって処理されるため、インターフェイス機能を子オブジェクトに委任できません。 TFormクラスはTinterfacedObjectから継承せず、Delphiは複数の継承をサポートしていないため、TAggregatedObjectまたはTContainedObjectを使用して継承されたオブジェクトのライフサイクルをFormに渡すことはできません。したがって、TInterfacedObjectを継承チェーンに混在させることはできません。あるフォームが破棄され、フォームによって渡されたインターフェイス参照のいずれかを他のコードが保持している場合、この状況はアクセス違反につながる可能性があります。誰もがこの問題の良い解決策を考えることができますか?デルファイの一生の間にインターフェイスオブジェクトを配布するフォームの安全な方法は?
答えて
インターフェイスを子オブジェクトに委譲できます。そのオブジェクトにフォームへの内部ポインタが含まれているだけで、必要に応じてフォームのコントロールにアクセスできます。
TAggregateObject
またはTContainedObject
をご利用いただけます。フォームはTInterfacedObject
から派生する必要はありません。彼らは必要ないすべてはIInterface
インタフェースポインタで、TComponent
がIInterface
から派生(および参照カウントを無効にする_AddRef()
と_Release()
が上書きされます)ので、あなたが必要IInterface
ポインタとして(TComponent
子孫である)フォーム自体を渡すことができます。
残っている唯一の問題は、アクティブなインターフェイス参照が他のコードによって保持されている間にフォームを閉じることです。最も簡単な解決策は、1)フォームが終了している間にそれらの参照を保持しないようにそのコードを書き換えるか、または2)それらの参照が解放されるまでフォームを閉じることを許可しないことです。
注:消費者がTComponentから派生している場合にのみ、これは機能します。フォームからあなたが(すべてのTComponentの上で利用可能)IInterfaceComponentReference
を照会することができます死んだ言及を避けるために
、そのインターフェイス上GetComponent
を呼び出し、返されたコンポーネント/フォームのFreeNotification
に自分自身を添付します。今、何が起こる
は次のとおりです。フォームは、その操作などAComponent
とopRemove
としての地位を消費者(フォーム)にNotification
メソッドを呼び出すことによって、自分自身を破壊しようとしていることをすべて「listners」を通知します破棄されますとき。したがって、あなたはあなたのインターフェイス参照をゼロにすることができます。 しかし、オブジェクト参照とインタフェース参照は同じであってはならないことに注意してください。 不要な通話を避けるために通知が不要な場合は、RemoveFreeNotification
に電話してください。
TSomeConsumer = class(TComponent)
private
FInterfaceToAService: ISomeInterface;
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
procedure SetService(const Value: ISomeInterface);
end;
procedure TSomeConsumer.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = TObject(FInterfaceToAService)) then
SetService(nil); // Takes care of niling the interface as well.
end;
procedure TSomeConsumer.SetService(const Value: ISomeInterface);
var
comRef: IInterfaceComponentReference;
begin
if Supports(FInterfaceToAService, IInterfaceComponentReference, comRef) then
comRef.GetComponent.RemoveFreeNotification(self);
FInterfaceToAService := Value;
if Supports(FInterfaceToAService, IInterfaceComponentReference, comRef) then
comRef.GetComponent.FreeNotification(self);
end;
ニース!私はそれについて知らなかった。あなたのステートメントで少し拡張することができます - "しかし、オブジェクト参照とインターフェイス参照が等しくあってはならないことに注意してください。" –
まあ、いくつかの理由: a)すべての呼び出しで新しいインタフェースオブジェクトを返すかもしれない 'QueryInterface'のカスタム実装を作ることができます。 b)次にInterfaceをプロパティ(Win32)に委譲することができます。これにより、毎回新しいObjectを作成することができます。 c)TObject.GetInterfaceを実装すると、アドレスにinterfaceOffsetが追加されます。 オブジェクトキャストへの新しく導入された(Delphi 2010)インターフェイスは、基本的に、オブジェクトのエントリアドレスを返すマーカーインターフェイスを照会することによって実行されます。 –
オブジェクトとインターフェイスの参照が等しく、プログラマが間違った状況を作り出す最も一般的な間違いは何ですか? –
- 1. ソフトウェア配布のための安全な方法
- 2. フォームを偽造するのを止める安全な方法
- 3. gensimのLDAトピックの単語の完全な配布方法は?
- 4. Powershell:配布グループの完全なリストを取得する方法
- 5. ポインタ配列の一部を再割り当てする安全な方法
- 6. カードと端末の間に安全なチャネルを生成する
- 7. SQLカラムに対するユーザ生成式の安全な方法
- 8. cloud9.ioのワークスペース(コンテナ)間にアプリワークロードを配布する方法は?
- 9. 一般的な方法でこのキャストは安全ですか?
- 10. PHPプロセス間で一意にキューを配布する最適な方法
- 11. フォームでのParsley.js検証の安全な使用方法
- 12. 安全な方法
- 13. 生産時にジャンゴ昆布でセロリを使うのは安全ですか?
- 14. Xamarinフォーム:ユーザーが時間を変更するのを防ぐ安全な方法はありますか?
- 15. MYSQLをWindowsフォームに接続するための最も安全な方法C#
- 16. 安全な方法は、bashの
- 17. 安全な方法と安全でない方法のPlay Frameworkコントローラ。可能?
- 18. フォームをredux形式で安全にする方法
- 19. WCFでクライアントとサーバー間の安全な通信を実装する方法は?
- 20. 安全なページに安全でないコンテンツを表示する方法
- 21. フォームは安全ですか?
- 22. 私はFirefoxのウェブエクステンションを安全でないサーバーに自己配布することができます
- 23. generic型のコレクションを配列に安全に変換する方法は?
- 24. これはフォーム要素をブロックする安全な方法です
- 25. フォームの安全ワードプレスCMS
- 26. 並行実行に安全な一時ファイル名を作成する方法は?
- 27. 一様分布のランダムビットセットを生成する方法
- 28. スレッド安全な方法
- 29. プロパティの一部への安全なアクセス
- 30. この方法は安全ですか?
ルボー、私のコードを改訂するためにその情報を使用します。 –
遅れてご質問をお待ちしていますが、TAggregatedObjectの代わりにTContainedObjectを使用するタイミングを説明する良いリファレンスを教えてください。私はしばらくの間、Delphiのヘルプを見てきましたし、実際にユースケースの違いを洗い出すことはできません。 –