mulle_objc: root objects and unloadable runtimes
Continued from mulle_objc: ivar layout with @property.
You want to write a plug-in for some C interface of another application. You figure out that you can solve the problem very easily in Objective-C, so why not do it ?
Examining a plug-in architecture
How would this look on Windows, where a plug-in is typically a DLL?
- The plug-in container would call
to load your DLL. When the DLL is loaded it will get a call to
- The plug-in container will rendezvous with your code by looking up known functions via GetProcAddress and call them.
- Eventually your DLL may become ejected with
FreeLibrary. You will get another call to
DllMain, this time with
A plug-in can be loaded and unloaded in succession - multiple times - by the same process.
Provisions in mulle_objc for loading and unloading Objective-C
When you are loading in Objective-C code, the code will immediately start
to construct a runtime and class-hierarchy. Possibly instances will be created
+load already. These hidden objects are almost impossible to get rid of
in traditional ObjC runtimes. (1)
Then your code executes, which will create more instances. Not all of them will
be reclaimable by enclosing
So when it comes to unloading, the runtime should get rid of all it’s classes and caches. Without classes, instances are useless and all of them should be removed too. (3)
MulleObjC maintains the whole object graph
If you create an object in mulle_objc, that is not owned by a
it must be declared a root object. There are five different kind of root objects
|Threads||MulleObjC maintains a list of
|Placeholders||Placeholders of class clusters (like
|Others||All other root objects (like for instance NSApp) use the
struct _mulle_objc_runtime is retain counted
When the retain count of the runtime reaches zero in
_mulle_objc_release_runtime, the runtime will self
_mulle_objc_runtime_dealloc. This function will untie the
runtime from the current thread and free all resources.
struct _mulle_objc_runtime may be thread-local
If you define
MULLE_OBJC_THREAD_LOCAL_RUNTIME when compiling all your code,
the runtime will not be global but instead exist on a per-thread basis. This
has the following consequences:
- Objects created by a thread refer to a different class system and can not be shared with objects of another thread.
- Calls that need the runtime are a lot slower, because the runtime has to be
You should determine on a per-case basis, if this feature is useful to you. The runtime ensures, that you can not mix “global” runtime and “thread local” runtime code. The default is “global”.