I closed my previous post with an observation that the code for initialising an iOS user interface programmatically, as translated from equivalent Objective-C, contained a potential gotcha. I now have a little more time to expand on that.
This is the code we ended up with last time:
method AppDelegate.application(application: UIApplication) didFinishLaunchingWithOptions(launchOptions: NSDictionary): Boolean; begin // Override point for customization after application launch. window := UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds); window.backgroundColor := UIColor.whiteColor; // Create an instance of our view controller // then set it as the window's root view controller var mainViewController := MainViewController.alloc.init; window.rootViewController := mainViewController; window.makeKeyAndVisible; result := true; end;
You might notice that I have now figured out how to extend the language support of the syntax highlighter plugin I use with WordPress, and having implemented an Oxygene “brush” I can now present Oxygene source without having to resort to screen grabs! 🙂
The potential gotcha is on lines 12 and 13 (highlighted) in the use of two different identifiers each called MainViewController. There is an apparent difference between them in that one is named with an initial lowercase “m” while the other has an initial capital “M“.
In Objective-C this is fine, since that language is case sensitive and – in common with C# for example – it is quite a common convention to see instance identifiers being named for the class they represent, with only this case difference to distinguish them (one of the reasons I personally dislike C style languages, incidentally).
But Oxygene is not case sensitive.
Because we have introduced an in-line variable declaration, from line 13 onwards both mainViewController and MainViewController will refer to the variable – an instance of the class – not the class itself.
This can be avoided in two ways:
- Use a different name for the variable
- Namespace qualify any references to the class from that point on
I personally favour the first of these.
In addition I favour not using in-line variable declarations for precisely this reason, that it potentially changes scope resolutions part-way through a method body. Its use in this case was intended only to illustrate the fact that this technique can be preserved directly when translating from Objective-C.
Had this variable been declared at the top of the method, the potential conflict would have been identified much more quickly since in that scenario the Oxygene compiler issues a warning that the MainViewController reference in the method body differs in case from the “initial declaration”.
This warning does not arise in the in-line declaration case, and arguably rightly so, since in that case the two identifiers are, well, identifiably distinct until after the initialisation of the variable has taken place. i.e. the code as written does not actually contain any problem arising from this potential gotcha. It is only a potential gotcha.
But these have a nasty habit of becoming actual gotchas when you least expect it, which is why I prefer to avoid them. 🙂
So that deals with the vestigial issue from that previous post and I am thankfully finding myself at last with more time to spend with Oxygene. High on my list of things to explore is the extent to which non-platform specific code can be shared between the different “flavours” of Oxygene.
All I know at this stage is that it is not only possible but obviously desirable, so that we may write applications that specialise their UI as appropriate to the different platforms with their different UI and UX needs, whilst avoiding having to duplicate any non-UI code.