Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy should I not use "if Assigned()" before accessing objects?
    primarykey
    data
    text
    <p>This question is a continuance of a particular comment from people on stackoverflow which I've seen a few different times now. I, along with the developer who taught me Delphi, in order to keep things safe, have always put a check <code>if assigned()</code> before freeing objects, and before doing other various things. However, I'm now told that I should <em>not</em> be adding this check. I'd like to know if there is any difference in how the application compiles/runs if I do this, or if it won't affect the result at all...</p> <pre><code>if assigned(SomeObject) then SomeObject.Free; </code></pre> <p>Let's say I have a form, and I'm creating a bitmap object in the background upon the form's creation, and freeing it when I'm done with it. Now I guess my problem is I got too used to putting this check on a lot of my code when I'm trying to access objects which might potentially have been free'd at some point. I've been using it even when it's not necessary. I like to be thorough...</p> <pre><code>unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FBitmap: TBitmap; public function LoadBitmap(const Filename: String): Bool; property Bitmap: TBitmap read FBitmap; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin FBitmap:= TBitmap.Create; LoadBitmap('C:\Some Sample Bitmap.bmp'); end; procedure TForm1.FormDestroy(Sender: TObject); begin if assigned(FBitmap) then begin //&lt;----- //Do some routine to close file FBitmap.Free; end; end; function TForm1.LoadBitmap(const Filename: String): Bool; var EM: String; function CheckFile: Bool; begin Result:= False; //Check validity of file, return True if valid bitmap, etc. end; begin Result:= False; EM:= ''; if assigned(FBitmap) then begin //&lt;----- if FileExists(Filename) then begin if CheckFile then begin try FBitmap.LoadFromFile(Filename); except on e: exception do begin EM:= EM + 'Failure loading bitmap: ' + e.Message + #10; end; end; end else begin EM:= EM + 'Specified file is not a valid bitmap.' + #10; end; end else begin EM:= EM + 'Specified filename does not exist.' + #10; end; end else begin EM:= EM + 'Bitmap object is not assigned.' + #10; end; if EM &lt;&gt; '' then begin raise Exception.Create('Failed to load bitmap: ' + #10 + EM); end; end; end. </code></pre> <p>Now let's say I'm introducing a new custom list object called <code>TMyList</code> of <code>TMyListItem</code>. For each item in this list, of course I have to create/free each item object. There's a few different ways of creating an item, as well as a few different ways of destroying an item (Add/Delete being the most common). I'm sure it's a very good practice to put this protection here...</p> <pre><code>procedure TMyList.Delete(const Index: Integer); var I: TMyListItem; begin if (Index &gt;= 0) and (Index &lt; FItems.Count) then begin I:= TMyListItem(FItems.Objects[Index]); if assigned(I) then begin //&lt;----- if I &lt;&gt; nil then begin I.DoSomethingBeforeFreeing('Some Param'); I.Free; end; end; FItems.Delete(Index); end else begin raise Exception.Create('My object index out of bounds ('+IntToStr(Index)+')'); end; end; </code></pre> <p>In many scenarios, at least I would hope that the object is still created before I try to free it. But you never know what slips might happen in the future where an object gets free'd before it's supposed to. I've always used this check, but now I'm being told I shouldn't, and I still don't understand why.</p> <hr> <p><strong>EDIT</strong></p> <p>Here's an example to try to explain to you why I have a habit of doing this:</p> <pre><code>procedure TForm1.FormDestroy(Sender: TObject); begin SomeCreatedObject.Free; if SomeCreatedObject = nil then ShowMessage('Object is nil') else ShowMessage('Object is not nil'); end; </code></pre> <p>My point is that <code>if SomeCreatedObject &lt;&gt; nil</code> is not the same as <code>if Assigned(SomeCreatedObject)</code> because after freeing <code>SomeCreatedObject</code>, it does not evaluate to <code>nil</code>. So both checks should be necessary.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload