title: Why we need to do retain for Objective-C object field?
body: <p>This is the code of the Delphi media player:</p>
  
  <pre><code>type
    TAVMedia = class(TMedia)
    private
      FPlayer: AVPlayer;
      FPlayerItem: AVPlayerItem;
    public
      constructor Create(const AFileName: string); override;
      destructor Destroy; override;
    end;
  
  constructor TAVMedia.Create(const AFileName: string);
  var aURL: NSUrl;
  begin
    inherited Create(AFileName);
    FPlayerItem := TAVPlayerItem.Wrap(TAVPlayerItem.OCClass.playerItemWithURL(URL));
    FPlayerItem.retain;
    FPlayer := TAVPlayer.Wrap(TAVPlayer.OCClass.playerWithPlayerItem(FPlayerItem));
    FPlayer.retain;
  end;
  
  destructor TAVMedia.Destroy;
  begin
    FPlayer.release;
    FPlayer := nil;
    FPlayerItem.release;
    FPlayerItem := nil;
    inherited Destroy;
  end;
  </code></pre>
  
  <p>I don't quite understand why they need to do <code>FPlayerItem.retain</code> and <code>FPlayer.retain</code>? <code>FPlayerItem</code> and <code>FPlayer</code> are object fields and not local variables so there is always a strong reference to them. So what is the purpose of the <code>retain</code> here?</p>
  
  <p>It seems that doing <code>FPlayer.release;</code> will also deallocate the <code>FPlayerItem</code>, so when later <code>FPlayerItem.release;</code> is called sometimes it triggers access violation (strangely not always).</p>
  
  <p><strong>Note</strong>: i still can't understand why i have an eaccessviolation so i decided to put here the full code of exactly what i did :</p>
  
  <pre><code>type
    TMyMedia = class(TObject)
    private
      FPlayer: AVPlayer;
      FPlayerItem: AVPlayerItem;
    public
      constructor Create;
      destructor Destroy; override;
    end;
  
  constructor TMyMedia.Create;
  begin
    inherited Create;
  
    P := TNSUrl.OCClass.URLWithString(StrToNSStr(aDataSource)); // Creates and returns an NSURL object initialized with a provided URL string
    if P = nil then raise EFileNotFoundException.Create(SFileNotFound); // If the URL string was malformed or nil, returns nil.
    aURL := TNSUrl.Wrap(P);
    try
  
      FPlayerItem := TAVPlayerItem.Wrap(TAVPlayerItem.OCClass.playerItemWithURL(URL));
      FPlayerItem.retain;
  
    finally
      aURL.release; // &lt;&lt; if i don't do this then i will not have any exception at the end ??? 
      aURL := nil;  // &lt;&lt;
    end;
  
  
    FPlayer := TAVPlayer.Wrap(TAVPlayer.OCClass.playerWithPlayerItem(FPlayerItem));
    FPlayer.retain;
  end;
  
  destructor TAVMedia.Destroy;
  begin
  
    ALLog('FPlayer.retainCount', inttostr(FPlayer.retainCount)); // =&gt; show 1
    ALLog('FPlayerItem.retainCount', inttostr(FPlayerItem.retainCount)); // =&gt; show 6
  
    FPlayer.release;
    FPlayer := nil;
  
    ALLog('FPlayerItem.retainCount', inttostr(FPlayerItem.retainCount)); // =&gt; show 1
    FPlayerItem.release; =&gt; here i receive Access violation at address 2156565 accessing address 68684458
  
    FPlayerItem := nil;
    inherited Destroy;
  end;
  </code></pre>