black magic and swizzling in objective-c

Post on 14-Apr-2017

59 Views

Category:

Engineering

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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.

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.

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));

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!

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.

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]);

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

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/

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.

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

http://cocoadev.com/wiki/MethodSwizzling

top related