Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
- Subject: Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
- From: DumberThanDanQuayle <email@hidden>
- Date: Sat, 25 Sep 2004 06:46:13 -0400
On Sep 24, 2004, at 11:32 PM, DumberThanDanQuayle wrote:
I think I have found my simple solution which writing common method
implementations in a separate file and using the C preprocessor macro
"#include" to insert that text into my classes where necessary like
this:
@implementation mySubClassWithWeakMultipleInheritence
#include "myCommonProtocolImpementation.m"
- (void)someSubClassSpecificMethod
{
NSLog(@"This is someSubClassSpecificMethod of
mySubClassWithWeakMultipleInheritence");
}
@end
The purpose of this post is to end this thread and add value to the
archives by clarifying a few points to future readers searching for
"Multiple Inheritance" techniques or work-a-rounds in Cocoa.
1.) The idea presented in the code snippet above, that is writing
individual method or whole protocol implementations in a separate file
and the using the C preprocessor "#include" directives to insert that
text into class definitions where need, seems to work very well and has
no serious drawbacks. To make things perfectly clear. the
"myCommonProtocolImpementation.m" would look something like this:
- (void)commonProtocolMethod
{
NSLog(@"This is the commonProtocolMethod of
myCommonProtocolImpementation ");
}
That is, you would _not_ have the common method implementations
sandwiched between "@implementation" and "@end" makers. We are simply
pasting in text here. This mean "myCommonProtocolImpementation.m"
will not independently compile, so it should not be added to any
targets (and if it was added to a target then remove it by deselecting
its target checkbox or dragging out of the target's file group in
XCode).
2.) Method swizzling is not general applicable for Multiple
Inheritance. As point out by Glenn Andreas, swizzled methods assume
that the instance variable ("ivar") structure is the same in both the
host and the surrogate method classes. More clearly, swizzled methods
think they are dealing with their native set of ivars. Merely having
using the same ivar name and type is not guarantied to work, and trying
to use this technique for Multiple Inheritance can generate some
twisted Obj-C runtimes. Furthermore, it is not absolutely necessary to
call "_objc_flush_caches_(Class)" after swizzling, because it merely
erases any stored reference to the native implementation for prior
calls. If you have not made any prior calls, such as swizzling on
"+initialize" there should be none to erase. If you do swizzle on
"+initilize," you should remember that any subclasses will also be
swizzling and should consider using a check like:
if(self == [MYSwizzledSuperClass class])
to eliminate redundant swizzling. More clearly, subclasses should just
inherit swizzled methods through the normal inheritance mechanism and
not be assigned them directly. Finally, some people have posted sample
method swizzling code elsewhere which implies that coping of
"Method->method_types" is necessary. Not is only is the coping of
"Method->method_types" not absolutely necessary, if you were swizzling
in a situation where "Method->method_types" (which refers to the method
argument classes or primitive types) were different between the host
and surrogate methods, you should really know what you are doing or be
prepared to get your hands dirty.
The source for _objc_flush_caches_(Class) and the rest of the Obj-C
runtime is part of Apple's Darwin Open Source project and available
here:
http://darwinsource.opendarwin.org/10.0.4/objc4-208/runtime/objc-
class.m
This post is an excellent and annotated example of how to swizzle
methods: http://www.cocoabuilder.com/archive/message/2001/2/26/28280
Note that "_objc_flush_caches_(Class)" is otherwise a "private"
function of the Obj-C runtime (it is not declared in <objc/objc.h>) and
to avoid implicitly defining it in the swizzling code that function is
declared to be externally defined like so:
void extern _objc_flush_caches_(Class);
3.) Finally, if the use of protocols and common method implementations
do not satisfy your needs for Multiple Inheritance you might consider
using the message forwarding mechanism with [NSObject fowardInvocation]
or perhaps ultimately look at isa swizzling to dynamically change the
class of your objects. Note that [NSObject poseAsClass] appears to
merely allow classes to appear as it's super class.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden