objective superman - sash zats, wondermall
TRANSCRIPT
Objec&ve(Superman
Looks%familiar?
// NSMutableDictionary *counters, id key
if (!counters[key]) { counters[key] = @1;} else { NSUInteger i = [counters[key] integerValue]; counters[key] = @(i + 1);}
NSInteger count = [counters[key] integerValue];
We#can#do#be*er!
// NSCountedSet *counters, id key
[counters addObject:key];
NSUInteger count = [counters countForObject:key];
When%the%scheiße%hits%the%fan
• How%o&en%did%you%use%NSCountedSet?
• Know%what%is%there%at%your%disposal.
• !%hits%the%fan%=%"
Swizzling
The$way$to$swizzle
As#done#by#those#fine#gentleman:
• Mike&Ash:&"Method&Replacement&for&Fun&and&Profit"1
• Jonathan&"Wolf"&Rentzsch:&JRSwizzle2
2"h$ps://github.com/rentzsch/jrswizzle
1"h$ps://www.mikeash.com/pyblog/friday9qa920109019299method9replacement9for9fun9and9profit.html
The$way$to$swizzle@implementation UIViewController (EveryDayImSwizzling)
+ (void)load { [UIViewController jr_swizzleMethod:@selector(viewDidLoad) withMethod:@selector(xyz_viewDidLoad) error:nil];}
- (void)xyz_viewDidLoad { NSLog(@"I was here"); [self xyz_viewDidLoad];}
- (void)viewDidLoad {
NSLog(@"!");}
@end
The$right$way$to$swizzle3
• Each&method&has&implicit&id&&&_cmd
• Read&about&other&people&suffering4
4"h$p://petersteinberger.com/blog/2014/a9story9about9swizzling9the9right9way9and9touch9forwarding
3"h$p://blog.newrelic.com/2014/04/16/right:way:to:swizzle/
Demo%!
Swizzling()ps
• Prefix:(xyz_
• Calling(original(method:([self xyz_swizzleMe]
• If(swizzling(ini9alisers,(hint(ARC(seman9cs(by(adding(__attribute__((objc_method_family(init)))5
• The(right(way(to(swizzle:(func9ons(or(blocks,(remember(_cmd.
5"h$p://clang.llvm.org/docs/A$ributeReference.html#objc>method>family
Proper&es(inspec&on6
6"Ivars,"too."Remember"ivars?
Proper&es(introspec&on:(cool(stuff.
• List&all&the&proper.es:&name&/&type.
• Type,&even&if&nil&or&incorrect&type.
• Accessors&(readonly,©,&getter=isHidden…).
• Applica.ons:&automa.c&parsing,&valida.on,&IOC7&etc.
7"h$ps://github.com/tomersh/AppleGuice
Proper&es(introspec&on:(Mantle8
• Reduces(amount(of(boilerplate
• Serialize(to(JSON,(CoreData,(XML(!
• Deserialize(dates,(enums,(URLs(etc.
• ValidaBon.
• NSCopying(and(NSCoding.
8"h$ps://github.com/Mantle/Mantle
Demo%!
Proper&es(introspec&on(&ps
• Does¬&include&proper0es&from&superclasses,&while5loop&that&class&chain!
• Automa0c&parsing&is&dangerous&(just&like&self5driving&cars).
• Assigning&through&KVC,&always&check&for&readonly.
• Did&you&call&me&lazy?
Dynamic(class(crea-on
Dynamic(class(crea-on
• Just&like&a®ular&subclassing.
• Leave&no&trace:&class&does¬&exist&in&assembly.
• Dynamically&assemble&class&on&the&fly.
• Simulate&mul>ple&inheritance.
Demo%!
Dynamic(class(crea-on:(-ps
• UIKit'&'Founda/on'use'it'twice.'Twice!
• Seems'like'a'very'esoteric'exercise.
• You'want'to'know'it's'there'when'you'need'it.
• When'do'you'need'it?
Let's&build&KVO
Let's&build&KVO
• We$want$to$know$when$any$given$property$is$set
• What$a$coincidence,$we$just$learned$everything$we$need!
• Create$a$custom$subclass.
• Swizzle$se@er$for$specified$property.
• Set$our$subclass$as$observed$object$class.
Demo%!
Let's&build&KVO
• Curiosity
• KVO-for-ge1er
• KVO-for-collec4ons
• Inject-side-effects-into-se1ers-and-ge1ers-of-all-subclasses-of-a-certain-class,-e.g.-createdAt,-updatedAt,-lastAccessedAt
Conclusion
• <objc/runtime.h>"!="App"Store.
• I"say,"test"it,"Mantle"is"a"produc7on"
grade"code.
• Swizzling"to"patch"UIKit"gotchas!9
• Objec7veDC"run7me"is"its"own"
kryptonite.
• "Wax"on,"wax"off""–"it"comes"together,"
when"you"need"it.
9"h$p://petersteinberger.com
One$more$thing...
Unicode(2015:(Diversity
S"ll$no$black$cat$emoji$!
Thank&you• This&talk&and&demos&github.com/zats/Presenta9ons
• Objec9ve=C&run9me&opensource.apple.com
• twiAer.com/zats
• github.com/zats
• 9nder.com/zats