• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >Is _objc_flush_caches_(Class) necessary to swizzle methods? (From: DumberThanDanQuayle <email@hidden>)
 >Re: Is _objc_flush_caches_(Class) necessary to swizzle methods? (From: Glenn Andreas <email@hidden>)
 >Re: Is _objc_flush_caches_(Class) necessary to swizzle methods? (From: DumberThanDanQuayle <email@hidden>)
 >Re: Is _objc_flush_caches_(Class) necessary to swizzle methods? (From: Glenn Andreas <email@hidden>)
 >Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?) (From: DumberThanDanQuayle <email@hidden>)
 >Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?) (From: Ondra Cada <email@hidden>)
 >Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?) (From: DumberThanDanQuayle <email@hidden>)

  • Prev by Date: How to draw a rectangle in a NSView
  • Next by Date: How to do a progress window the "right way"?
  • Previous by thread: Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
  • Next by thread: Re: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
  • Index(es):
    • Date
    • Thread