• 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: Is _objc_flush_caches_(Class) necessary to swizzle methods?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?


  • Subject: Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?
  • From: Glenn Andreas <email@hidden>
  • Date: Fri, 24 Sep 2004 11:18:27 -0500

At 11:56 AM -0400 9/24/04, DumberThanDanQuayle wrote:
Glenn, thanks for the response.

On Sep 24, 2004, at 9:55 AM, Glenn Andreas wrote:

At 4:47 AM -0400 9/24/04, DumberThanDanQuayle wrote:

Does anybody know what the story with "_objc_flush_caches_(Class)" and method swizzling really is?

From my understanding delving the depths of the runtime, _objc_flush_caches_ is needed because the runtime maintains cache of recent methods & imps used when dispatching. So once it figures out that [foo something] is at 0x123400, it keeps that in the cache for Foo.


If you change foo something to point to 0x567800, the cache will still refer to the old version, so the next time you call [foo something] 0x123400 gets executed, and not your new 0x567800.

If it is a method that has never been called, you could probably get away without calling it.

Great, now I know what _objc_flush_caches_(Class) does and that it should have nothing to do with my runtime's "strangeness" because I am method swizzling to achieve something like multiple inheritance and I am attempting it in +initialize. So my instance methods should have never been called by that time.

The source for the runtime is part of Darwin, so you can "use the source, Luke" (it's filled with all sorts of interesting tidbits, too).


More importantly, though, is that method swizzling is probably not a good strategy to achieve something like multiple inheritance. Not the least problem is that if you are attempt to have one class "look" like another class, it will need to have the same instance vars (instance vars are referenced as offsets from "self", so if you use a method for class Foo and the receiver is actually class Bar, the code thinks that you have Foo's ivar structure when you have Bar's ivar structure - perhaps this was the debugging problem you saw before?)

On the other hand, method forwarding and its friends can achieve a great deal of the functionality that you may be looking for (and provides a way to simulate changing the class heirarchy at runtime - after all, the delegate of an NSWindow is used to make that window behave like something other than the default NSWindow).



OTOH, I've never seen a problem with inheritence/ivars when doing this (since that information doesn't use any of the method dispatch cache anyway).

The type of runtime "strangeness" I am now continuing to experience is not something simple like the old method is called instead of the new one. I am talking about the bizarre, like a case of an infinite loop being generate when calling [super someMethod] and somehow the runtime decides the receiving method is in a _subclass_ (which in turn calls [super someMethod]). My latest oddity is the swizzling of two classes mixes up their "init" methods. It is as if my entire runtime is being randomly swizzled (or at least those of classes related to being modified).

It does sound like something painful is happening to your runtime.

This brings me to my next question. Is +initialize a bad place to swizzle for some reason? Should I try waiting until all classes have been initialized first? Moreover should I type-check in +initialize so that subclasses do not redundantly swizzle methods?

One potential problem is categories are often loaded later, which will replace this.


And yes, you should probably check self == [MyClass class] to avoid getting initialize messages from subclasses.


Another concern I have is that the CocoaDev page I referenced also reassigns Method->method_types when swizzling. I suppose this not necessary useless the arguments required for the methods being swapped are actually different, but I am not sure.

Changing method types when swizzling - ew. That sounds like very bad mojo (since the compiled code was generated for different parameter types, and suddenly, if you've got something else...)



--
Glenn Andreas email@hidden <http://www.gandreas.com/> oh my!
Mad, Bad, and Dangerous to Know
_______________________________________________
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
  • Follow-Ups:
    • Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
      • From: DumberThanDanQuayle <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>)

  • Prev by Date: Re: Unit testing framework suggestions?
  • Next by Date: Re: Getting system information (was Re: Newbie: My first app, how to?)
  • Previous by thread: Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?
  • Next by thread: Multiple Inheritence (Was: Is _objc_flush_caches_(Class) necessary to swizzle methods?)
  • Index(es):
    • Date
    • Thread