NOTE: If you have read this post before, it has been updated recently to include further changes that remove all leaks generated by the demo project.

Recently there was a posting in the Embarcadero forums about problems with creating a secondary form, showing it modally, then destroying it; namely that the app exits without warning after showing the form a number of times. There were also no crash logs for the app. This is a classic symptom that the app suffers from a memory leak.

I created a test application, attached Instruments to the app, and sure enough, the app was leaking memory. I had also hooked in a handler for the application events so I could see if the app is receiving any low memory warnings. Please refer to the attached project that demos the problem, and also serves as an example of how to hook into application events.

Instruments is a companion application that comes with Xcode that helps debug your iOS and OS X apps. To run the application, click on the Xcode menu item, click Open Developer Tool, then click Instruments:

When Instruments starts, it prompts for a template to use. For checking Leaks in your app, select the Leaks template:

and click the Choose button. Click the Choose Target dropdown, and make sure your device is checked. To select your app, click Choose Target again. If your app is already running, you can click Attach To Process and select your app from the list of running apps:

otherwise select your app from the Choose Target submenu. In this case, your app obviously need to have been deployed to your device.

Select the Leaks category from the list of Instruments on the left, and click the red record button at the top left. I tend to uncheck Automatic Snapshotting, so that I can examine leaks on an ad-hoc basis. To turn it off, simply uncheck the checkbox:

If you have it turned off, and want to check a status of any leaks, click the Snapshot Now button. The following image is the leak status of the test project, after I’ve clicked Button 1 to open the modal window, then clicked Button 2 to close it, twice:

As can be seen, there’s a bunch of leaks, and given the count of each leak, they occur each time the form is “destroyed”. Thanks to a post by Cristian Peta in the thread mentioned earlier, to plug the TSettingsFont leak involves making a copy of the FMX.Graphics unit, placing it somewhere in the compiler search path, and making the following modification:

type
  TSettingsFont = class (TFont)
  private
    [Weak] FTextSettings: TTextSettings;  // Add the [Weak] directive on this line
  protected
    procedure DoChanged; override;

I’ve also been alerted by William Brookfield to a workaround in this QC report. Thanks also to Babak Yaghoobi for his help regarding this leak. This time make a copy of the FMX.Platform.iOS unit (or modify a copy you might have made from another patch), and make the following mods. Firstly in TPlatformCocoaTouch.ShowWindowModal:

  finally
    BackView.removeFromSuperview;
    BackView.release; // Add this line
  end;
  Result := AForm.ModalResult;
end;

..and in TPlatformCocoaTouch.DestroyWindow:

procedure TPlatformCocoaTouch.DestroyWindow(const AForm: TCommonCustomForm);
begin
  if Assigned(AForm.Handle) then
  begin
    WindowHandleToPlatform(AForm.Handle).View.removeFromSuperview;
    WindowHandleToPlatform(AForm.Handle).View.release;  // Add this line
  end;
end;

Rebuilding the app, attaching Instruments to it and recording as before results in no more leaks! I hope this has been of use, either to fix leaks in your app or just as a guide to using Instruments.