<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html comments</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Mon, 17 Aug 2026 10:00:41 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Geoff - 2015-07-07 17:57:59</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>I tried using this technique on a class level method instead of an instance method. In addition to replacing class_getInstanceMethod with class_getClassMethod, I needed to wrap "self" with object_getClass() in the class_replaceMethod() function.
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;Method origMethod= class_getClassMethod(self, @selector(foo));
&lt;br /&gt;class_replaceMethod(object_getClass(self), @selector(foo), (IMP)overrideFoo, method_getTypeEncoding(origMethod));
&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;I'm assuming that is because class_getClassMethod is expecting to be working with Class level methods while class_replaceMethod could work with either. Is this correct?</description><guid isPermaLink="true">b0162cf96fe5ef67dfb86ab77634374f</guid><pubDate>Tue, 07 Jul 2015 17:57:59 GMT</pubDate></item><item><title>Steven - 2014-04-16 10:26:27</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Mike, &lt;code&gt;class_replaceMethod&lt;/code&gt; does not return the imp of the superclass method. If the method was newly added to the class, &lt;code&gt;gOrigDrawRect&lt;/code&gt; is 0.
&lt;br /&gt;
&lt;br /&gt;In that case, I add an extra &lt;code&gt;method_getImplementation&lt;/code&gt;, using the method I get from &lt;code&gt;class_getInstanceMethod&lt;/code&gt;. That should return the nearest superclass IMP of the method.</description><guid isPermaLink="true">0321482fbc83942b6b61f31d34a15228</guid><pubDate>Wed, 16 Apr 2014 10:26:27 GMT</pubDate></item><item><title>mikeash - 2013-09-27 14:33:04</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Actually, in C, a pointer is definitely not a pointer. There is no guarantee that pointers of different types have the same internal representation. This is especially true for function pointers. What you say happens to be the case on popular architectures we use today, but it's not part of C.
&lt;br /&gt;
&lt;br /&gt;In any case, the &lt;i&gt;type&lt;/i&gt; gets converted, even if the value remains the same.</description><guid isPermaLink="true">c50b220722b1c982583da366673f5668</guid><pubDate>Fri, 27 Sep 2013 14:33:04 GMT</pubDate></item><item><title>martin - 2013-09-15 12:25:45</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>you wrote "and thanks to the magic of C, the void * gets implicitly converted to the right pointer type anyway.)"
&lt;br /&gt;
&lt;br /&gt;i'm sure you are aware that nothing get's "converted" here, in C a pointer is a pointer, 4 or 8 bytes are copied, that's all.
&lt;br /&gt;
&lt;br /&gt;(not to be confused by the real magic Objective C can do converting types on the fly when setting them, setting a BOOL or float from a NSNumber for example, using setValueForKey.
&lt;br /&gt;</description><guid isPermaLink="true">575c96f2cf9759ef5a0e95683b214cfe</guid><pubDate>Sun, 15 Sep 2013 12:25:45 GMT</pubDate></item><item><title>mikeash - 2013-08-20 13:38:33</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>If you call through to the original implementation first, you can the retrieve the copied string from the regular pasteboard.</description><guid isPermaLink="true">f2d7f2b5567bd4fd1967bf961d035e78</guid><pubDate>Tue, 20 Aug 2013 13:38:33 GMT</pubDate></item><item><title>chandan - 2013-08-20 10:33:03</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>I am swizzling Copy: and Paste: method of UIResponder. I have to write the copied content to a private pasteboard.
&lt;br /&gt;
&lt;br /&gt;- (void)copyToPrivatePasteboard:(id)sender
&lt;br /&gt;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UIPasteboard *privatePasteboard = [self getPrivatePasteboard];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[privatePasteboard setString:@""];//How to get the copied string to store in pasteboard.
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;How can i write copied string to pasteboard. The parameter i am getting is of type id. If i convert it to NSString, it won't be proper because it is the sender who is calling this method (UIMenuController).</description><guid isPermaLink="true">91ac9be3acf1a9bba94ca02ae7bcfd8d</guid><pubDate>Tue, 20 Aug 2013 10:33:03 GMT</pubDate></item><item><title>Whitney Young - 2013-02-18 18:43:47</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>I just came back to this, and was re-reading some of the comments. Mike, your comment from 2010-01-29 doesn't seem quite right. The class_replaceMethod returns NULL if the method was added rather than replaced. I think the simplified version would be:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;Method origMethod = class_getInstanceMethod(self, @selector(drawRect:));
&lt;br /&gt;gOrigDrawRect = (void *)method_getImplementation(origMethod);
&lt;br /&gt;class_replaceMethod(self, @selector(drawRect:), (IMP)OverrideDrawRect, method_getTypeEncoding(origMethod))
&lt;br /&gt;&lt;/code&gt;</description><guid isPermaLink="true">0062f510b2d1bd51c9ed5c112210115e</guid><pubDate>Mon, 18 Feb 2013 18:43:47 GMT</pubDate></item><item><title>Dmytro - 2012-11-16 22:06:55</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Can I replace class method (declared as + (void) methodname ....) ? I successfully replace instance method ( -(void) methodname ...), but can't class method...</description><guid isPermaLink="true">9fa2825a4273e4fd591c625d90e45075</guid><pubDate>Fri, 16 Nov 2012 22:06:55 GMT</pubDate></item><item><title>Bernhard - 2012-10-18 17:46:26</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Thank you, Mike, for this great article!
&lt;br /&gt;
&lt;br /&gt;I think, though, that you should have mentioned that in order to use the class_...() and method_...() functions, one needs to include the libobjc.A.dylib library in the Xcode Target and then #import &amp;lt;objc/runtime.h&amp;gt; in the source file.
&lt;br /&gt;</description><guid isPermaLink="true">4c12cfcc3244b9a939eb8263eb5f4cfa</guid><pubDate>Thu, 18 Oct 2012 17:46:26 GMT</pubDate></item><item><title>mikeash - 2011-05-19 22:44:22</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>&lt;code&gt;class_getInstanceMethod&lt;/code&gt; will return the superclass's implementation if the class in question doesn't have one of its own, so everything still works as desired.</description><guid isPermaLink="true">564705ad9746ac1735ae2ed14ce54e89</guid><pubDate>Thu, 19 May 2011 22:44:22 GMT</pubDate></item><item><title>Ling Wang - 2011-05-19 05:37:49</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>In MethodSwizzle, what if overrideSEL is not implemented in the class in question, but rather in a superclass?</description><guid isPermaLink="true">732aa426e2eb7395cb68da7450e1a5fd</guid><pubDate>Thu, 19 May 2011 05:37:49 GMT</pubDate></item><item><title>mikeash - 2010-08-14 15:36:10</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>That's an interesting case that I hadn't thought of. Thanks for pointing it out.</description><guid isPermaLink="true">99d3f906b607839cc2142e4fdf54d431</guid><pubDate>Sat, 14 Aug 2010 15:36:10 GMT</pubDate></item><item><title>Ryan Petrich - 2010-08-14 05:23:26</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Your "Direct Override" method fails to handle the case where two hooks are applied to the same method: first on a descendent class that does not override the method and again on the super class.
&lt;br /&gt;
&lt;br /&gt;Example: Application has classes Dog and Mammal.  Mammal has a reproduceWith: method. MadScientist uses your Direct Override technique to hook -[Dog reproduceWith:] and inject his additional code.  EvilGeneticist uses any other hook technique to hook -[Mammal reproduceWith:].
&lt;br /&gt;Later, -[Dog reproduceWith:] is called; only MadScientist's hook is runs instead of both MadScientist and EvilGeneticist's hooks.
&lt;br /&gt;
&lt;br /&gt;This is not a theoretical problem--the iPhone jailbreak community has encountered this issue numerous times and has standardized on two libraries: MobileSubstrate emits ARM bytecode at runtime to avoid it, and CaptainHook avoids it through macro trickery.</description><guid isPermaLink="true">b96dc7508645990fc3e9a1cfbbf9c1c8</guid><pubDate>Sat, 14 Aug 2010 05:23:26 GMT</pubDate></item><item><title>None - 2010-05-18 10:38:35</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Hi, i have some questions about doing the swizzle on some application's class method when under 64bit.
&lt;br /&gt;
&lt;br /&gt;in 32bit, the code will run as i expected, but when in 64bit, i get this error:
&lt;br /&gt;
&lt;br /&gt;Error loading XXX:  dlopen(XXX, 123): Symbol not found: _OBJC_CLASS_$_SomeClass
&lt;br /&gt;&amp;nbsp;&amp;nbsp;Referenced from: XXX
&lt;br /&gt;&amp;nbsp;&amp;nbsp;Expected in: flat namespace
&lt;br /&gt;&amp;nbsp;in XXX
&lt;br /&gt;
&lt;br /&gt;i googled for solutions, and i get some answers like:
&lt;br /&gt;
&lt;br /&gt;&lt;a href="http://groups.google.com/group/f-script/browse_thread/thread/09f07a3771032de4"&gt;http://groups.google.com/group/f-script/browse_thread/thread/09f07a3771032de4&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;i go and see the code, which does not fix the error.
&lt;br /&gt;
&lt;br /&gt;i use JRSwizzle's + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_
&lt;br /&gt;
&lt;br /&gt;thx :)</description><guid isPermaLink="true">6849c76f14245a5344440224f226e71a</guid><pubDate>Tue, 18 May 2010 10:38:35 GMT</pubDate></item><item><title>mikeash - 2010-02-10 01:35:07</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>My test program has a bug in it: in &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; should be of type &lt;code&gt;char&lt;/code&gt;. Still fails as described with that change made.
&lt;br /&gt;
&lt;br /&gt;I forgot to mention: even if none of your parameters are of the offending types, there's still nothing which guarantees that the calling conventions will match between a vararg call with certain argument types and a non-vararg receiver with those same types. It's far more likely to work (and I think the ABIs of the platforms that OS X runs on may guarantee it on those particular platforms) but still unsafe.</description><guid isPermaLink="true">c881308d097e26487cedd8c30fbfa35a</guid><pubDate>Wed, 10 Feb 2010 01:35:07 GMT</pubDate></item><item><title>mikeash - 2010-02-10 01:13:19</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>It gets worse. Because of C's type promotion rules, you &lt;i&gt;can't&lt;/i&gt; pass &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;short&lt;/code&gt;, or &lt;code&gt;char&lt;/code&gt; (or the unsigned counterparts of the last two) through a vararg function, because they get promoted to &lt;code&gt;double&lt;/code&gt; and &lt;code&gt;int&lt;/code&gt;. This code illustrates the problem:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;void Tester(int ign, float x, char y)
&lt;br /&gt;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("float: %f  char: %d\n", x, y);
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;int main(int argc, char **argv)
&lt;br /&gt;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float x = 42;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float y = 42;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Tester(0, x, y);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void (*TesterAlt)(int, ...) = (void *)Tester;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TesterAlt(0, x, y);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
&lt;br /&gt;}&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;On my computer, the second invocation prints &lt;code&gt;float: 0.000000  char: 0&lt;/code&gt;.
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;objc_msgSend&lt;/code&gt; doesn't use vararg calling conventions. The convention it "uses" is any convention which is compatible with a pointer return value, and placing the first two arguments in a place where they can be expected. &lt;code&gt;objc_msgSend&lt;/code&gt; completely ignores all remaining arguments, and lets them pass through unhindered. The caller and the eventual callee (after &lt;code&gt;objc_msgSend&lt;/code&gt; looks it up and jumps to it) still have to agree on how those work, and if the caller thinks they're varargs and the callee doesn't, they won't get along.
&lt;br /&gt;
&lt;br /&gt;You must cast &lt;i&gt;all&lt;/i&gt; calls to &lt;code&gt;objc_msgSend&lt;/code&gt; and its variants in order to have the compiler generate the correct code. Failing to do so will work for many cases, but only because you're getting lucky. The same goes for casting &lt;code&gt;IMP&lt;/code&gt;s.</description><guid isPermaLink="true">3abf26dd771b7bf2f28d04106993c07b</guid><pubDate>Wed, 10 Feb 2010 01:13:19 GMT</pubDate></item><item><title>Matt Gallagher - 2010-02-10 00:06:59</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Okay, I was overlooking the fact that the declaration of IMP actually declares the third parameter to be a "...". You are correct; I retract my point about not using varargs.
&lt;br /&gt;
&lt;br /&gt;However, this is the calling convention used by objc_msgSend, and by extension all methods except the objc_msgSend_(st/fp/fp2)ret methods. But yes, (st/fp/fp2)ret methods require a correct cast of the IMP or other special handling to work. Fortunately, the compiler is smart enough to give a hard error if you try to do this without a cast -- it doesn't slip through unnoticed.
&lt;br /&gt;
&lt;br /&gt;I find the bigger problem is that without a signature, all regular parameters need to be correctly typed or they won't be passed correctly (since the compiler can infer the wrong register or stack size). This can cause problems without so much as a warning if you're not careful.</description><guid isPermaLink="true">9f0fb70d5814e741d5f1b44c11ab234e</guid><pubDate>Wed, 10 Feb 2010 00:06:59 GMT</pubDate></item><item><title>mikeash - 2010-02-09 17:54:41</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>By the way, lest this objection seem too theoretical, consider what happens if you use that macro for a method which returns a struct.</description><guid isPermaLink="true">208e5d7f0922be81f0407c2dc3d8def9</guid><pubDate>Tue, 09 Feb 2010 17:54:41 GMT</pubDate></item><item><title>mikeash - 2010-02-09 17:46:01</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>No need to leave, I welcome all reasonable discussion.
&lt;br /&gt;
&lt;br /&gt;Your macro looks like this:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;#define invokeSupersequent(...) \
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;([self getImplementationOf:_cmd \
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;after:impOfCallingMethod(self, _cmd)]) \
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(self, _cmd, ##__VA_ARGS__)&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;-getImplementationOf:&lt;/code&gt; is defined to return an &lt;code&gt;IMP&lt;/code&gt;, which takes variable arguments after the &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;_cmd&lt;/code&gt; parameters. This macro does not cast the &lt;code&gt;IMP&lt;/code&gt; to a different function pointer type (and indeed could not, as it doesn't have enough information to do so). This means that the &lt;code&gt;IMP&lt;/code&gt; is being called with variable argument calling conventions. Or did I miss some place where everything gets cast to the right function pointer type before calling?</description><guid isPermaLink="true">2187fe6d3be7ff24797e0fd702387b5e</guid><pubDate>Tue, 09 Feb 2010 17:46:01 GMT</pubDate></item><item><title>Matt Gallagher - 2010-02-09 13:01:14</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>On the point of vararg method calling conventions though... the supersequent code doesn't actually use them. The macro is variable argument but is expanded to a non-vararg parameter list by the preprocessor. The ObjC compiler sees (and compiles) regular parameters only.
&lt;br /&gt;
&lt;br /&gt;Sorry to have gotten in the way. I'll see myself out...</description><guid isPermaLink="true">fba251c88cbf854ba785dce64cb88139</guid><pubDate>Tue, 09 Feb 2010 13:01:14 GMT</pubDate></item><item><title>Matt Gallagher - 2010-02-09 12:47:48</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>'fraidy cat :-)
&lt;br /&gt;
&lt;br /&gt;But yes, the supersequent method stuff is a hack for the same reason any "undocumented" stuff is: it can be gone at a moment's notice. It relies on the way that things just happen to be done.
&lt;br /&gt;
&lt;br /&gt;As for multiple categories though... the way the ObjC 1.0/2.0 runtimes just happen to be written, all categories &lt;i&gt;are&lt;/i&gt; preserved in the order that they are loaded. Technically load order is deterministic but it's fragile -- generally, the system libraries will be loaded before your code, but not always.
&lt;br /&gt;
&lt;br /&gt;But don't ship code with it unless you want to get burned.</description><guid isPermaLink="true">a0bd6d67e0b111f661194cd2e388a6b8</guid><pubDate>Tue, 09 Feb 2010 12:47:48 GMT</pubDate></item><item><title>mikeash - 2010-02-01 18:40:11</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Extreme hacking, and not the good kind. The technique as a whole relies on the runtime keeping the old IMP in the class method list after adding a category. As far as I know, this behavior is not guaranteed. This also won't chain: if you have two or more methods all implemented in a category (one of these could be in Apple's code, beyond your control) then it's still not guaranteed who "wins". There's also a big problem with the macro itself, in that it assumes the method signature is compatible with vararg calling conventions, something that's not at all guaranteed. Gallagher doesn't mention &lt;i&gt;any&lt;/i&gt; of these caveats, which worries me greatly. He says that this technique is mainly good for debugging because it's slow. I say that it's &lt;i&gt;only&lt;/i&gt; good for debugging because you don't have any guarantees that it'll actually work.</description><guid isPermaLink="true">c68b51a2dd6f030405ed1750f4c1c240</guid><pubDate>Mon, 01 Feb 2010 18:40:11 GMT</pubDate></item><item><title>Cédric Luthi - 2010-02-01 09:21:11</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Actually, it is technically possible to call the original implementation of a method overridden in a category. Matt Gallagher explains how in his &lt;b&gt;Supersequent implementation&lt;/b&gt; blog post: &lt;a href="http://cocoawithlove.com/2008/03/supersequent-implementation.html"&gt;http://cocoawithlove.com/2008/03/supersequent-implementation.html&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;Warning: extreme hacking inside!</description><guid isPermaLink="true">a9fcc2df6080949ee460984ae384325c</guid><pubDate>Mon, 01 Feb 2010 09:21:11 GMT</pubDate></item><item><title>mikeash - 2010-01-29 22:24:08</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>I'd always pondered the potential trouble of giving the original method the wrong &lt;code&gt;_cmd&lt;/code&gt;, but never came across a place where it mattered in practice. Interesting!</description><guid isPermaLink="true">e703d5b8a1c9fdf4320630415c7a97ea</guid><pubDate>Fri, 29 Jan 2010 22:24:08 GMT</pubDate></item><item><title>Whitney Young - 2010-01-29 21:00:59</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>One interesting place that I've seen method swizzling fail is with the following NSResponder methods:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;mouseEntered:
&lt;br /&gt;mouseExited:
&lt;br /&gt;mouseMoved:
&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;If I remember correctly, these methods all use an IMP that actually determines what to do based on the _cmd argument.  Therefore, when you swizzle, you end up passing override_mouseEntered: as _cmd instead of a value that it knows how to handle.
&lt;br /&gt;
&lt;br /&gt;The direct override should not suffer from this problem since it's passing on _cmd correctly.</description><guid isPermaLink="true">e2c2af6395d9e8fca559895bbd434ee8</guid><pubDate>Fri, 29 Jan 2010 21:00:59 GMT</pubDate></item><item><title>mikeash - 2010-01-29 20:36:08</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>Oh nice, I completely missed that aspect of that function, and that it returns the old implementation. So the Direct Override's &lt;code&gt;+load&lt;/code&gt; method can be cut down to just this:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;Method origMethod = class_getInstanceMethod(self, @selector(drawRect:));
&lt;br /&gt;gOrigDrawRect = (void *)class_replaceMethod(self, @selector(drawRect:), (IMP)OverrideDrawRect, method_getTypeEncoding(origMethod))&lt;/code&gt;</description><guid isPermaLink="true">f5023c50c92ad5a107ec81f5e904c595</guid><pubDate>Fri, 29 Jan 2010 20:36:08 GMT</pubDate></item><item><title>Remy Demarest (Psy|) - 2010-01-29 20:11:43</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>It's not needed to make two separate codes for when the method is implemented in the class or when it's only implemented in the super-class.
&lt;br /&gt;The runtime-function class_replaceMethod() takes care of that, if the method is defined in the class, then the replacement is done, if it's defined in a super-class then the function adds the method to the class. So you simply need to retrieve the "old" implementation (that might be the super-class's implementation) and call it in your function replacement.</description><guid isPermaLink="true">87e62a023f72cb94e940ea24eeb14065</guid><pubDate>Fri, 29 Jan 2010 20:11:43 GMT</pubDate></item><item><title>Joel Bernstein - 2010-01-29 19:43:25</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html#comments</link><description>If you're going to use method 2, you could do a lot worse than using Jonathan Rentzsch's JRSwizzle class:
&lt;br /&gt;
&lt;br /&gt;&lt;a href="http://github.com/rentzsch/jrswizzle"&gt;http://github.com/rentzsch/jrswizzle&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;It takes care of most of the mindless busywork and edge cases.</description><guid isPermaLink="true">69e654422862d57fb174eb1a21b97ae2</guid><pubDate>Fri, 29 Jan 2010 19:43:25 GMT</pubDate></item></channel></rss>
