سؤال

في عالم لا يزال فيه التخصيص اليدوي للذاكرة والمؤشرات هو السائد (بورلاند دلفي) أحتاج إلى حل عام لما أعتقد أنه مشكلة عامة:

في لحظة معينة يمكن الرجوع إلى كائن ما من أماكن متعددة (قوائم، كائنات أخرى، ...).هل هناك طريقة جيدة لتتبع كل هذه المراجع حتى أتمكن من تحديثها عند تدمير الكائن؟­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

هل كانت مفيدة؟

المحلول

إذا كنت تريد إخطار الآخرين بالتغييرات، فيجب عليك تنفيذ "نمط المراقب".لقد قامت شركة دلفي بذلك بالفعل من أجل أحفاد TComponent.يمكنك استدعاء الأسلوب TComponent.FreeNotification وإعلام الكائن الخاص بك عند إتلاف المكون الآخر.يفعل ذلك عن طريق استدعاء طريقة الإخطار.يمكنك إزالة نفسك من قائمة الإشعارات عن طريق الاتصال بـ TComponent.RemoveFreeNotification.انظر أيضا هذه الصفحة.

معظم جامعي البيانات المهملة لا يسمحون لك بالحصول على قائمة المراجع، لذلك لن يساعدوا في هذه الحالة.يمكن أن تقوم دلفي بإحصاء المراجع إذا كنت ستستخدم واجهات، ولكن مرة أخرى تحتاج إلى تتبع المراجع بنفسك.

نصائح أخرى

لا أستطيع أن أفهم تمامًا سبب رغبتك في القيام بذلك.من المؤكد أنك ستتحقق فقط من مرجع في Not Nil قبل استخدامه؟

على أية حال، هناك حلان محتملان سأفكر فيهما:

  1. اجعل مدير الكائنات يعد مرجعًا خاصًا به.
  2. إنشاء فئة مدير العد المرجعي.

من المحتمل أن أقوم بإضافة وظائف AddRef() و ReleaseRef() إما إلى المدير أو إلى فئة علم المرجع.يمكنك بعد ذلك استخدامها للتحقق من عدد المراجع الموجودة في أي وقت.COM يفعل ذلك بهذه الطريقة.

ستدير الفئة المدركة للمرجع عدد المراجع الخاص بها فقط.يمكن للمدير استخدام الخريطة لربط المؤشرات بعدد صحيح للعد.

هل تحاول تعقب من يشير إلى كائن ما حتى تتمكن من مسح تلك المراجع عند إتلاف الكائن، أم أنك تحاول تعقب الوقت الذي يكون فيه تدمير الكائن آمنًا؟

إذا كان الأخير يبدو أنك تبحث عن جامع القمامة.لم أتعامل مطلقًا مع دلفي، لذا لا أعرف ما إذا كانت هناك GCs يمكنك استخدامها، لكنني سأكون مندهشًا إذا لم يكن هناك.

إذا كان الأول، فربما لن يساعد GC.إذا كانت دلفي تدعم OOP/الوراثة (بصراحة لا أعرف إذا كانت تفعل ذلك) فيمكنك القيام بشيء مثل هذا (الكود الكاذب):

// Anything that will use one of your tracked objects implements this interface
interface ITrackedObjectUser {
  public void objectDestroyed(TrackedObject o);
}

// All objects you want to track extends this class
class TrackedObject {
  private List<ITrackedObjectUser> users;

  public void registerRef(ITrackedObjectUser u) {
    users.add(u);
  }

  public void destroy() {
    foreach(ITrackedObjectUser u in users) {
      u.objectDestroyed(this);
    }
  }
}

في الأساس، عندما تقوم بإضافة أحد الكائنات المتعقبة إلى مجموعة، فإن هذه المجموعة ستسجل نفسها مع هذا الكائن.عندما يتم تدمير الكائن (أعتقد أنك ستستدعي التدمير () في أداة تدمير الكائن) فإن الكائن يشير إلى المجموعة بأنه تم تدميره حتى تتمكن المجموعة من القيام بكل ما تحتاجه.

لسوء الحظ، هذا ليس حلاً جيدًا حقًا إذا كنت تريد استخدام المجموعات المضمنة.سيتعين عليك كتابة كائنات المجموعة الخاصة بك (يمكنهم فقط تغليف الكائنات المضمنة).وسيتطلب الأمر التأكد من قيامك بالتسجيل في كل مكان تريد تتبع الكائن فيه.وهذا ليس ما أعتبره حلاً "سعيدًا"، على الرغم من أنه ربما لن يكون سيئًا للغاية بالنسبة للمشاريع الصغيرة.آمل بشكل أساسي أن تساعد هذه الفكرة في توليد أفكار أخرى.:)

هل هناك سبب محدد لرغبتك في ذلك؟هل تواجه مشاكل مع المؤشرات المارقة، أم أنك تعتقد أنها قد تكون مشكلة في يوم من الأيام؟

IMHO لن تكون هناك مشكلة إذا قمت بتصميم التطبيق الخاص بك بشكل صحيح، واستخدام الأنماط المناسبة يساعدك حقًا.

بعض المعلومات عن الطرز:

http://delphi.about.com/od/oopindelphi/a/aa010201a.htm

http://www.obsof.com/delphi_tips/pattern.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top