Difference between revisions of "Cocoa Internals/Memory Management"

From Lazarus wiki
Jump to navigationJump to search
Line 10: Line 10:
  
 
A new sub-class of NSObject is declared, overriding its alloc (constructor) and dealloc (destructor) methods. Overridden methods are providing a logging output.
 
A new sub-class of NSObject is declared, overriding its alloc (constructor) and dealloc (destructor) methods. Overridden methods are providing a logging output.
<source lang="delphi">
+
<source lang="delphi">program project1;
program project1;
 
  
 
{$mode delphi}{$H+}
 
{$mode delphi}{$H+}
Line 42: Line 41:
 
   inherited dealloc;
 
   inherited dealloc;
 
end;
 
end;
 
  
 
procedure MakeObject;
 
procedure MakeObject;
Line 56: Line 54:
 
   MakeObject;
 
   MakeObject;
 
   MakeObject;
 
   MakeObject;
end.
+
end.</source>
</source>
 
 
The output of calling such process would be:
 
The output of calling such process would be:
 
  alloc:  3206800
 
  alloc:  3206800
Line 66: Line 63:
 
  dealloc: 3206800
 
  dealloc: 3206800
 
This is happening, because whenever an object is allocated, it's reference count is set to 1. Calling release method reduced the reference counter by 1. If reference count becomes zero, objc runtime - is calling objects destructor - dealloc.
 
This is happening, because whenever an object is allocated, it's reference count is set to 1. Calling release method reduced the reference counter by 1. If reference count becomes zero, objc runtime - is calling objects destructor - dealloc.
 
+
===Leaking===
If the routine MakeObject function
+
If MakeObject procedure is modified as following:
 +
<source lang="delphi">procedure MakeObject;
 +
var
 +
  obj : NSMyObject;
 +
begin
 +
  obj:=NSMyObject.alloc.init;
 +
  obj.release;
 +
end;</source>
  
 
==ObjC Object Leaks==
 
==ObjC Object Leaks==

Revision as of 02:04, 25 December 2017

All Objective-C objects are reference counted objects. Once the count reaches zero - the object is freed.

The modern Objective-C (or Swift) recommends (strongly, fiercely) to use Automatic-Reference-Counting (ARC) support. FPC support for Objective-C was started way before ARC became highly recommended and was part of the language. Right now Objective-C 2.0 syntax provides the language level support for ARC, while FPC doesn't have those (yet?). All Cocoa Widgetset code cannot doesn't rely on ARC and using reference and dereference manually.

Memory Management

As mentioned earlier - all Cocoa objects are reference counted objects. They should be allocated via a class constructor (typically alloc()) and be released via release() method (rather than calling a "destructor" dealloc).

Consider the following code example:

A new sub-class of NSObject is declared, overriding its alloc (constructor) and dealloc (destructor) methods. Overridden methods are providing a logging output.

program project1;

{$mode delphi}{$H+}
{$modeswitch objectivec1}
{$modeswitch objectivec2}

uses CocoaAll;

type

  { NSMyObject }

  NSMyObject = objcclass(NSObject)
  public
    class function alloc: id; override;
    procedure dealloc; override;
  end;

{ NSMyObject }

class function NSMyObject.alloc: id;
begin
  Result:=inherited alloc;
  writeln('alloc:   ', PtrUInt(Result));
end;

procedure NSMyObject.dealloc;
begin
  writeln('dealloc: ', PtrUInt(Self));
  inherited dealloc;
end;

procedure MakeObject;
var
  obj : NSMyObject;
begin
  obj:=NSMyObject.alloc.init;
  obj.release;
end;

begin
  MakeObject;
  MakeObject;
  MakeObject;
end.

The output of calling such process would be:

alloc:   3206800
dealloc: 3206800
alloc:   3206800
dealloc: 3206800
alloc:   3206800
dealloc: 3206800

This is happening, because whenever an object is allocated, it's reference count is set to 1. Calling release method reduced the reference counter by 1. If reference count becomes zero, objc runtime - is calling objects destructor - dealloc.

Leaking

If MakeObject procedure is modified as following:

procedure MakeObject;
var
  obj : NSMyObject;
begin
  obj:=NSMyObject.alloc.init;
  obj.release;
end;

ObjC Object Leaks

Free Pascal debugging unit heaptrc is only able to track leaking of memory allocated via Pascal Run-time memory management. It's not able to track allocations made via C-runtime/Obj-C memory manager.

Apple provides an external tools to keep tracking of ObjC allocations.

Xcode Instruments

One of the

See Also