By default, class and interface types on the Island platform are native Island types, adhering to Elements' own object model created specifically for Island. Class types will descend from
System.Object or one of it's descendants, forming a single tree of classes.
On some Island sub-platforms, additional, platform-native object and/or interface models are supported. Classes or interfaces defined using these models adhere to a different object model, and live in their own class hierarchy, with classes typically descending from a root object class provided by the platform.
Right now, the following object models are supported:
Darwin sub-platform for Cocoa, two additional object models are (or will be) supported, in addition to native Island classes. These models are available both for classes and interfaces
- Cocoa – Objective-C objects (descending from
Foundation.NSObject) and protocols.
- Swift – Native Swift objects (descending from
Swift.Object) and protocols.
The Darwin sub-platform provides full support for the Objective-C class model, as needed to interact with the core Cocoa APIs from Foundation over AppKit/UIKit to more specialized frameworks provided by Apple and third parties.
Swift object model is not to be confused with using the Swift language dialect provided by Silver. As with all five OOP Elements languages, classes written in Silver can be native Island classes, Objective-C Runtime classes or, optionally, Swift Runtime classes.
On selected platforms (currently desktop Windows, Linux and macOS, Elements is introducing support for working directly and natively with types and APIs from Delphi-built packages.
- Delphi – to work with Delphi-build packages, types and APIs.
Refer to the upcoming Delphi SDKs topic for more details.
Delphi support is limited to platforms and architectures your particular version of Delphi supports, and will for now not extend to mobile platforms.
Note: Delphi SDK support is still highly experimetal
While mostly useful on the Windows platform, Interface types on any Island sub-platform can, optionally, be cdeclared as COM-compatible interfaces for interaction with other COM-compatible environments.
- COM for declaring and using COM-compatible interfaces based on
Please refer to the COM topic for more details.
Mixing Object Models
Objects and interfaces from the different object models can freely interact with each other. Classes declared in one model may have fields, properties or method parameters of the other model, and the interaction will work seamlessly as one would expect.
The same interfaces can be implemented by classes of either model, allowing code to interact with the types without needing to be aware of the underlying class model – even though the classes themselves do no share a common ancestor. Similarly, Island-native generics can be used with classes or interfaces of either model, seamlessly and without runtime overhead (e.g. an Island-native
List<T> may be instantiated to hold Cocoa objects, Island Objects or Swift objects).
Automatic wrapping and unwrapping will happen when assigning objects to a base
TObject-type variable of a different object model, using wrapper classes provided by Island RTL, such as
CocoaWrappedIslandObject et al, but this will rarely affect strongly typed user code.
Default Object Model
As indicated above, the default object model for classes and interfaces normally is the native Island object model, and classes and interfaces without ancestor will become part of this model.
A new "Default Object Model" Compiler Option is provided to change that. By setting this option to, e.g., "Cocoa", classes and interfaces declared without ancestor will become Objective-C types by default instead, making the compiler behave much like the classic Cocoa platform, where all classes were based on the Objective-C runtime.
This option is useful when writing code that is highly Cocoa-centric (such as macOS or iOS GUI apps), and best used with the New Cocoa Mode that provides additional compatibility with classic Cocoa projects.
Of course Cocoa classes in this mode can still freely interact with native Island types and Swift Runtime types, as described in the previous section.
The same goes for setting a default object model of "Delphi" or – later, when fully supported – "Swift".
Note that the default object model only applies to types declared without explicit ancestor. Classes that declare an ancestor will automatically be of the same object model as said ancestor, so for example inheriting a class from
TObject (or any of its descendants, such as
TForm) will automatically make it a "Delphi" object model class.
Instead of providing an ancestor, you call also specify a class's object mode by attaching its model as an Aspect.
Setting a default object model also brings the
ObjectModel namespace into scope (where
ObjectModel is the actual name, e.g.
RemObjects.Elements.System.Cocoa. This is how Common standard type names (mainly
Exception) get mapped to their appropriate model.
For setting the default to "Cocoa" brings
RemObjects.Elements.System.Cocoa.String into scope, which aliases to
NSString; setting it to "Delphi" brings in
RemObjects.Elements.System.Delphi.String, which aliases to
DelphiUnicodeString, depending on version, and
RemObjects.Elements.System.Delphi.Object, which aliases to
In C#, the
string keywords will map to whatever
String type is thus in scope.
Determining a Type's Model
modelOf() system function accepts as its single parameter the name of a specific type know at compile time or a generic type parameter in scope, and returns a string value describing it's model, currently one of
- Class and Interface Types in Oxygene
- Object Model Aspects:
- Default Object Model Compiler Option
- Legacy Cocoa Mode