Mega Code Archive

 
Categories / Delphi / Functions
 

Understanding Delphis NIL value and the Assigned RTL Function

Title: Understanding Delphi's NIL value and the Assigned RTL Function In Delphi, the NIL constant (also a reserved word) is a pointer value defined as "not-assigned" or "pointer to nothing" or "undetermined". Nil is defined as : const Nil = Pointer(0); NIL vs. Objects - Class Instances In Delphi, a class defines a structure consisting of fields, methods, and properties. Instances of a class are called objects. In the following example code, the TDeveloper is a class (defining one property, "Experience"): type TDeveloper = class private fExperience: integer; published property Experience : integer read fExperience write fExperience; end; aDeveloper is an object - an instance of the TDeveloper class: var aDeveloper : TDeveloper; A variable of a class type is actually a pointer that references an object. Like other pointers, class-type variables can hold the NIL value. Here's how to test if aDeveloper is "assigned": if aDeveloper = nil then begin ShowMessage('aDeveloper is NIL') ; aDeveloper := TDeveloper.Create; aDeveloper.Experience := 9; ShowMessage('aDeveloper is now created.') ; ShowMessage(Format('Developer experience: %d',[aDeveloper.Experience])) ; end The code above tests if aDeveloper points to a valid object, if not creates an instance and assigns a value to the Experience property. The RTL function Assigned cal aslo be used to determine if the pointer or procedure referenced is not nil. Thus, "if aDeveloper = nil" is equal to "if NOT Assigned(aDeveloper)". Note that you need to make sure aDeveloper is fred when no longer needed, to deallocate the memory used by aDeveloper: if Assigned(aDeveloper) then begin ShowMessage('aDeveloper exists - freeing it ...') ; aDeveloper.Free; end; Since Free checks for a nil reference before calling Destroy, you should *never* assign an object pointer to nil before calling Free. NIL vs. Method (Procedure) Pointers Almost all the code you write is executed, directly or indirectly, in response to events. The code that responds directly to an event -called an event handler - is a Delphi procedure. Events are special properties of a method-pointer type. For example, the OnClick event of a TButton control, is a property - a method pointer. The event handler for the OnClick event is a procedure of a method-pointer type. At design time, Delphi helps you "connect" events with event-handlers: you double-click a Button to create the OnClick event handler. Since the OnClick event of a TButton is a method pointer, thus a pointer, you can assign NIL to it. To know if a TButton instance "aButton" has been assigned the OnClick event handler, use the following code: if Assigned(Button1.OnClick) then ShowMessage('Something will happen if you click Button1') ; Since you can assign NIL to a method pointer, you can detach an event handler from an event. Here's how to create a "click-once" button handler: //Button1's OnClick handler on Form1 procedure TForm1.Button1Click(Sender: TObject) ; begin // // do whatever needed to handle // Button1's OnClick event // only the first time // //detach this procedure (event-handler) //from the OnClick event Button1.OnClick := nil; end;