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
LoadLibrary
to load your DLL. When the DLL is loaded it will get a call to
DllMain
with
DLL_PROCESS_ATTACH
. - 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 withDLL_PROCESS_DETACH
for that.
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
inside +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 NSAutoreleasePool
s. (2)
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 NSAutoreleasePool
it must be declared a root object. There are five different kind of root objects
Type | Description |
---|---|
Threads | MulleObjC maintains a list of NSThread objects. Threads are the holders of the NSAutoreleasePools . |
Placeholders | Placeholders of class clusters (like NSString ) are also maintained separately. Class-cluster placeholders implement the MulleObjCClassCluster protocol, which implements the appropriate runtime mechanics. |
Singletons | Singletons (like +[NSNotificationCenter defaultCenter] ) have their own runtime list. Singletons should implement the MulleObjCSingleton protocol. |
Others | All other root objects (like for instance NSApp) use the NSObject protocol methods -_becomeRootObject to announce their “rootness” and -_resignAsRootObject to reliquish it. |
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
destruct with _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
retrieved with
mulle_thread_tss_get
.
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”.
Continue to mulle_objc: method searching and accidental override protection.
Post a comment
All comments are held for moderation; basic HTML formatting accepted.