zoukankan      html  css  js  c++  java
  • Weak References

    http://docwiki.embarcadero.com/RADStudio/Seattle/en/Automatic_Reference_Counting_in_Delphi_Mobile_Compilers#Weak_References

    Weak References

    Another important concept for ARC is the role of weak references, which you can create by tagging them with [weak] attribute. Suppose that two objects refer to each other using a field, and an external variable refers to the first. The reference count of the first object will be 2 (the external variable, and the second object), while the reference count of the second object is 1. Now, as the external variable goes out of scope, the two objects' reference count remains 1, and they remain in memory indefinitely.

    To solve this type of situation, and many similar scenarios, is to use a weak reference to break the circular references when the last external reference goes out of scope.

    A weak reference is a reference to an object that does not increase its reference count. To declare a weak reference, use the [weak] attribute, supported by the Delphi mobile compilers.

    Given the previous scenario, if the reference from the second object back to the first one is weak, as the external variable goes out of scope, both objects are destroyed. Here is an example of this situation:

    type
      TMyComplexClass = class;
     
      TMySimpleClass = class
      private
        [Weak] FOwnedBy: TMyComplexClass;
      public
        constructor Create();
        destructor Destroy (); override;
        procedure DoSomething(bRaise: Boolean = False);
      end;
     
      TMyComplexClass = class
      private
        fSimple: TMySimpleClass;
      public
        constructor Create();
        destructor Destroy (); override;
        class procedure CreateOnly;
      end;

    In the following code snippet, the constructor of the complex class creates an object of the other class:

    constructor TMyComplexClass.Create;
    begin
      inherited Create;
      FSimple := TMySimpleClass.Create;
      FSimple.FOwnedBy := self;
    end;

    Remember that the FOwnedBy field is a weak reference, so it does not increase the reference count of the object it refers to, in this case the current object (self).

    Given this class structure, we can write:

    class procedure TMyComplexClass.CreateOnly;
    var
      MyComplex: TMyComplexClass;
    begin
      MyComplex := TMyComplexClass.Create;
      MyComplex.fSimple.DoSomething;
    end;

    This causes no memory leak, given that the weak reference is properly used.

    As a further example of the use of weak references, note this code snippet in the Delphi RTL, part of the TComponent class declaration:

    type
      TComponent = class(TPersistent, IInterface,
        IInterfaceComponentReference)
      private
        [Weak] FOwner: TComponent;

    If you use the weak attribute in code compiled by one of the desktop Delphi compilers, the attribute is ignored. Using DCC32, you have to make sure that you add the proper code in the destructor of an "owner" object to also free the "owned" object. Calling Free is allowed, although the effect is different in the Delphi mobile compilers. The behavior is correct in both in most circumstances.

    Note: When an instance has its memory released, all active [weak] references are set to nil. Just as a strong (normal) reference, a [weak] variable can only be nil or reference a valid instance. This is the main reason why a weak reference should be assigned to a strong reference before being tested for nil and dereferenced. Assigning to a strong reference does not allow the instance to be released prematurely.
    var
      O: TComponent;// a strong reference
    begin
      O := FOwner;  // assigning a weak reference to a strong reference
      if O <> nil then
        O.<method>;// safe to dereference
    end;
    Note: You can only pass a [Weak] variable to a var or out parameter that is also marked as [Weak]. You cannot pass a regular strong reference to a [Weak] var or out parameter.
  • 相关阅读:
    js搜索输入关键词
    pc端,自适应屏幕分辨率
    js获取锚点名称 #
    yourphp读取分类名称{$Categorys[$r[catid]]['catname']}
    收缩菜单 css变样
    ajax成功跨域_自己写的
    json 是个什么东西?
    json_encode详解,转义
    跨域代码 手机号码
    php json_decode
  • 原文地址:https://www.cnblogs.com/cb168/p/5135825.html
Copyright © 2011-2022 走看看