Since Apple updated Xcode to version 8.3.x, iOS IPA deployment is broken with Delphi up to 10.2 (Tokyo). There is an official workaround, which basically instructs to download Xcode 8.2 and use that for now: http://docwiki.embarcadero.com/PlatformStatus/en/Main_Page#iOS_10 Unfortunately though, Apple started sending out notifications, that it won’t accept any builds created…Read More
Apple requires you to specify if your apps are using any form of encryption. If you do not use encryption, you have to confirm that in your app settings on iTunes Connect – this is not new, Apple started asking for that long time ago. Important to notice is though…Read More
These are the slides from my Mobile Dev and Test session on Rapid Prototyping Mobile Projects with Arduino and Open Hardware in San Diego. I’ll update later with links and more resources.
slides download (v0.9)
Main Site – www.visuino.com
Documentation – www.visuino.com/wiki
Instructables – www.instructables.com/member/BoianM/instructables/
Hackster.IO – www.hackster.io/visuino
YouTube – bit.ly/MitovYT
Blog – labpacks.blogspot.com
The Delphi compiler allows functions and procedures to be tagged with the inline directive to improve performance. If the function or procedure meets certain criteria, the compiler will insert code directly, rather than generating a call. Embarcadero docwiki gives a list of conditions under which inlining does or does not occur.
One of basic conditions says: within a unit, the body for an inline function should be defined before calls to the function are made.
TMS FixInsight 2017.04 introduces rule O805 “Inline marked routine comes after its call in the same unit”. Let’s check FMX and VCL code to see if Embarcadero follows their own rules. Short answer: it doesn’t.
I will give a couple of examples from Delphi 10.1 Berlin (version 24.0.22858.6822).
//at line 8529
procedure TWinControl.ReadState(Reader: TReader);
if FParent nil then Perform(CM_PARENTCTL3DCHANGED, 0, 0);
//at line 9010
procedure TWinControl.AlignControl(AControl: TControl);
if not HandleAllocated or (csDestroying in ComponentState) then Exit;
if FAlignLevel 0 then
Rect := GetClientRect;
//at line 9030
TWinControl.DisableAlign is an inline marked procedure. It is called at line 8531 and line 9019, but its body is defined after the calls – at line 9030. Obviously, this function will not be inlined.
One more example from another unit:
//at line 2430
if (Adapter.Count < 1) or (FDeleteLayout = nil) or ((FDeleteButtonIndex = -1) and
(FPrevDeleteButtonIndex = -1)) then
if (FListingService nil) and (TListingTransitionFeature.DeleteButtonSlide in FListingService.GetTransitionFeatures) then
FDeleteLayout.Width := DefaultDeleteButtonWidth * FDeleteModeTransitionAlpha;
FDeleteButton.Opacity := 1;
if FDeleteModeTransitionAlpha > 0 then
FDeleteLayout.Width := DefaultDeleteButtonWidth
FDeleteLayout.Width := 0;
FDeleteButton.Opacity := 0.5 + (FDeleteModeTransitionAlpha / 2);
FDeleteLayout.Height := GetItemHeight(FDeleteButtonIndex);
FDeleteLayout.Position.X := Width - FDeleteLayout.Width;
if FDeleteButtonIndex = -1 then
RelRect := GetItemRelRect(FPrevDeleteButtonIndex, LocalRect)
RelRect := GetItemRelRect(FDeleteButtonIndex, LocalRect);
FDeleteLayout.Position.Y := (RelRect.Top + RelRect.Bottom - FDeleteLayout.Height) / 2;
The method above contains two GetItemRelRect calls (lines 2457 and 2459), but both are before the actual GetItemRelRect body position in that unit (line 2868):
//at line 2868
function TListViewBase.GetItemRelRect(const Index: Integer; const LocRect: TRectF;
const SideSpace: Integer = 0): TRectF;
Result := RectF(LocRect.Left + FSideSpace + SideSpace, LocRect.Top + FSideSpace + FHeightSums[Index] - FScrollViewPos,
LocRect.Width - ((SideSpace + FSideSpace) * 2), GetItemHeight(Index));
if (FScrollBar nil) and (not HasTouchTracking) and FScrollBar.Visible then
Result.Right := Result.Right - FScrollBar.Width;
Despite being declared as inline, this method will not be inlined.
It is not a critical issue, but this makes inline directive useless. There are more occurrences of this issue in Vcl.ExtActns.pas, FMX.ASE.Lexer.pas, FMX.Graphics.pas, FMX.Types.pas, FMX.Utils.pas and FMX.ZOrder.Win.pas.
This means that inlining conditions are not easy to follow, even though at first glance inline directive seems to be an easy way to slightly optimize your code. TMS FixInsight may help to make inlining more useful by avoiding such mistakes.
You can download TMS FixInsight trial and check your own code.