17
Objective-C e o dinamismo da linguagem Diego Chohfi Turini @dchohfi [self SP]; Monday, March 19, 12

Objective-C e o dinamismo da linguagem

Embed Size (px)

Citation preview

Page 1: Objective-C e o dinamismo da linguagem

Objective-Ce o dinamismo da linguagem

Diego Chohfi Turini@dchohfi

[self SP];

Monday, March 19, 12

Page 2: Objective-C e o dinamismo da linguagem

Tipagem dinâmica,

Podemos chamar um método que não está declarado na sua interface.

Pato* patoFeio = [[Pato alloc] init];

[patoFeio late]; -> warning, não error.

OMG

Monday, March 19, 12

Page 3: Objective-C e o dinamismo da linguagem

Tipagem forte, mas...

...você pode associar qualquer tipo a um id

- (void) argumentoObjetoGenerico: (id) bijeto;//by @sr_valeriano :P

(referência a qualquer coisa em memória)

Ou obrigar que ele siga um protocolo

- (void) argumentoComProtocolo: (id<Protocolo>) bijeto;

@optional@required

Monday, March 19, 12

Page 4: Objective-C e o dinamismo da linguagem

Por segurança, ganhamos alguns métodos bacanas:

- (BOOL)isKindOfClass:(Class)aClass;- (BOOL)isMemberOfClass:(Class)aClass;- (BOOL)conformsToProtocol:(Protocol *)aProtocol;- (BOOL)respondsToSelector:(SEL)aSelector;

Mas como é feita a busca de métodos no objeto?No objeto? Na classe? Vai pensando..

Monday, March 19, 12

Page 5: Objective-C e o dinamismo da linguagem

@interface Burro : NSObject

- (void) zurra;

@end

Interface .h#import "Burro.h"

@implementation Burro

- (void) zurra{ NSLog(@"INON");//WTF?}

@end

Implementação .m

...nosso burro, que só sabe zurrar(?)

Agora,

Como podemos “pimpar” nosso burro? Quero que meu burro seja um pato!

Monday, March 19, 12

Page 6: Objective-C e o dinamismo da linguagem

#import "Burro.h"

@interface Burro (Pato)

- (void) quack;

@end

#import "Pato.h"

@implementation Burro (Pato)

- (void) quack{ NSLog(@"QUAAAACK");}

@end

=D

Com categories, nosso burro pode ser um pato! :P

Monday, March 19, 12

Page 7: Objective-C e o dinamismo da linguagem

não podemos adicionar variáveis deMas, com categories

instância :(

Monday, March 19, 12

Page 8: Objective-C e o dinamismo da linguagem

Com referência associativa você pode

(id) objc_getAssociatedObject(target, const* key);

objc_setAssociatedObject(target, const* key, id object, objc_AssociationPolicy policy);

*não sou eu

Coloque essa inhaca dentro de get/set que fica “lindo”

Monday, March 19, 12

Page 9: Objective-C e o dinamismo da linguagem

Na interface declaramos nossa propriedade

@property (nonatomic, retain) Objeto *atributo;

Meia lua pra trás-frente soco na implementaçãostatic const char *ObjetoKey = "ObjetoKey";

@dynamic atributo;//O atributo precisa ser @dynamic

- (Bijeto *)atributo { return (Bijeto *) objc_getAssociatedObject(self, ObjetoKey);}

- (void)setAtributo:(Bijeto *)atributo{ objc_setAssociatedObject(self, ObjetoKey, atributo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}

Monday, March 19, 12

Page 10: Objective-C e o dinamismo da linguagem

Voltando, como é feita a busca dos métodos?

NSObject contém apenas um atributo privado:

@interface NSObject <NSObject> { Class!isa;}

a busca então é feita na isa, um atributo do objeto.

Monday, March 19, 12

Page 11: Objective-C e o dinamismo da linguagem

Logo, a busca dos métodos é feita da seguinte forma:

+ (BOOL)resolveInstanceMethod:(SEL)sel;

YESid objc_msgSend(id self, SEL op, ...)

NOagora começa a brincadeira :P

Monday, March 19, 12

Page 12: Objective-C e o dinamismo da linguagem

-(id)forwardingTargetForSelector:(SEL)selector;

Você pode delegar a chamada do método para outro objeto, um atributo por exemplo:

E o method_missing?

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

NSMethodSignature é a compilação do SEL

-(void)forwardInvocation:(NSInvocation *)anInvocation;

forwardInvocation é o nosso method_missing :P

Monday, March 19, 12

Page 13: Objective-C e o dinamismo da linguagem

Mas afinal, o que é um método?

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);

void dynamicFoo(id self, SEL _cmd){ NSLog(@"dooing magic foo");}

Pato *patoDinamico = [[Pato alloc] init];

[patoDinamico foo]; //da erro

class_addMethod([patoDinamico class], @selector(foo), (IMP) dynamicFoo, "v@:");

[patoDinamico foo]; //agora lindão :P

Podemos adicionar um método na classe:

Monday, March 19, 12

Page 14: Objective-C e o dinamismo da linguagem

MethodSwizzling

Method fooMethod = class_getInstanceMethod([pato class], @selector(foo));Method barMethod = class_getInstanceMethod([pato class], @selector(bar));

method_exchangeImplementations(fooMethod, barMethod);

[patoDinamico foo]; //chama bar[patoDinamico bar]; //chama foo

ISA Switching

object_setClass(exPato, NSClassFromString(@"Burro"));

Monday, March 19, 12

Page 15: Objective-C e o dinamismo da linguagem

There’s no private variables :P

NSLog(@"%@", [patoDemo valueForKey:@"isa"]);

Monday, March 19, 12

Page 16: Objective-C e o dinamismo da linguagem

Obrigado :)

Monday, March 19, 12

Page 17: Objective-C e o dinamismo da linguagem

Referência:http://cocoasamurai.blogspot.com/2010/01/understanding-

objective-c-runtime.html

http://akitaonrails.com/2010/12/06/objective-c-method-missing

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ObjCRuntimeGuide/Introduction/

Introduction.html

Objective-C Pocket Reference

Monday, March 19, 12