|
Objectively
Object oriented framework for C.
|
A guide to declaring, implementing, and using your own types with Objectively.
Every Objectively type consists of three components:
1. The instance struct — starts with the parent type, then the zero-length interface member, then instance variables:
The interface member exists only so that $ can read its type with typeof; it holds nothing. The interface itself lives on the Class and is reached through Object::clazz. The member MUST directly follow the parent, where its pointer alignment costs no padding.
2. The interface struct — starts with the parent interface, then method function pointers:
3. The Class archetype — a single exported function that returns the Class:
Using your custom type is trivial. Instantiate it like you would any Objectively type.
See Hello.h and Hello.c for the full source.
There is no explicit setup or teardown with Objectively. To instantiate a type, simply call alloc from anywhere in your program. The first time a type is instantiated, its Class initializer, initialize, is called. Use initialize to setup your interface, override methods, or initialize a library your class wraps. When your application terminates, an optional Class destructor, destroy, is also called.
To invoke an instance method, use the $ macro.
To invoke a Class method, use the $$ macro.
To override a method, overwrite the function pointer from within your Class' initialize method.
To invoke a supertype's method implementation, use the super macro.
An instance carries no interface pointer of its own: $, cast, and isKindOfClass all resolve through Object::clazz. Reassigning clazz after allocation therefore changes an instance's behavior and its type identity together, immediately. This permits one-off Classes minted purely for behavior, with no struct, header, or archetype of their own:
The new Class inherits every method of the original, since _initialize copies the superclass interface before calling initialize. The instance struct MUST NOT change: a Class minted this way SHOULD reuse the superclass's instanceSize exactly, because the memory has already been allocated.
Objectively uses reference counting to govern object retention. Newly instantiated Objects have a reference count of 1. To retain a strong reference to an Object, call retain(obj). To relinquish it, call release(obj). Once an Object's reference count reaches 0, it is deallocated. Remember to balance every retain with a release.
A shared instance or singleton pattern can be achieved through Class methods and release-on-destroy.
Remember to wire up the desctructor in your Class' initialization block. See Once.h for details on do_once.
Objectively ships code templates that cut down the boilerplate of declaring and implementing a type — highly recommended. Install the Xcode template by building the Xcode project, or import the Eclipse CDT templates through the Eclipse CDT preferences.