Black magic and swizzling in Objective-C

12
Black magic and swizzling in Objective-C

Transcript of Black magic and swizzling in Objective-C

Page 1: Black magic and swizzling in Objective-C

Black magic and swizzling in Objective-C

Page 2: Black magic and swizzling in Objective-C

Me

iOS developer since 2008—first app, NetSketch was on the App Store the day it went live.

Published more than 20 apps, which have been featured on the App Store, demoed on stage at SXSW, covered by Macworld.

Currently growing Kodiak, a platform that makes it easy for you to build great educational apps.

Page 3: Black magic and swizzling in Objective-C

5 minute agenda

Today, we’ll learn about Objective-C method dispatching (and it’s beautiful simplicity.)

We’ll talk about Method Swizzling, a technique for doing very bad things.

We’ll see an example of some really cool stuff you can do with it.

Page 4: Black magic and swizzling in Objective-C

Obj-C is a thin layer

Objective-C is a thin wrapper on top of C, and the objc.h headers declare C functions that implement method invocation, properties and more. Objective-C calls can be translated into their C counterparts:

[targetselector];

objc_msgSend(target,@selector(selector));

Page 5: Black magic and swizzling in Objective-C

Methods in tablesEach class in Objective-C has a lookup table associating method names with selectors (which point to functions.)

Objective-C categories are simple: they allow you to add methods to the lookup table. You can add methods to classes that already exist!

Page 6: Black magic and swizzling in Objective-C

Method Swizzling

Categories let you add things to the method lookup table, which is cool and somewhat unique to Objective-C.

But what if I want to replace a method?

You can’t. Thanks for listening.

Page 7: Black magic and swizzling in Objective-C

But I can write C!@implementation NSString (Category) - (NSString)betterDescription { return @"Haha I win."; } @end

origMethod = class_getInstanceMethod([NSString class], @selector(description:)); altMethod = class_getInstanceMethod([NSString class], @selector(betterDescription:));

IMP temp = origMethod->method_imp; origMethod->method_imp = altMethod->method_imp; altMethod->method_imp = temp;

// What do you think this will do? NSLog([@”Hello World” description]);

Page 8: Black magic and swizzling in Objective-C

But... why?Reroute calls to methodA: to methodB: instead.

Generally, you make methodB: call through to methodA:, so the default behavior still exists.

Useful for logging, overriding behaviors, stubbing methods for unit testing.

Use with extreme care. You will break things badly.

HTTP://DARKDUST.NET/WRITINGS/OBJECTIVE-C/METHOD-SWIZZLING

Page 9: Black magic and swizzling in Objective-C

One use case: Spark

The Spark Inspector has been a side project of mine for about a year, and is finally going through App Store review.

Swizzles dozens of methods on core classes like UIView to provide an awesome debug view.

Demo time! https://sparkinspector.com/

Page 10: Black magic and swizzling in Objective-C

Secret SauceSo how did that work? We added a framework to our app and ran a line of code. What did that code do?

The Spark Inspector swizzles setFrame:, setNeedsDisplay: (and lots more), and sends information about changes to a Mac app.

The mac app uses this information to rebuild the view hierarchy.

Page 11: Black magic and swizzling in Objective-C

TakeawaysObjective-C is a beautifully simple language, and you can do some really powerful things with it.

In general, if you find yourself wanting to swizzle something, you’re doing it wrong. But there are great reasons to break the rules sometimes.

I’d be happy to send out free copies of the Spark Inspector app once it’s live. Follow it on Twitter @sparkinspector, and me @bengotow

Page 12: Black magic and swizzling in Objective-C

http://cocoadev.com/wiki/MethodSwizzling