SlideShare uma empresa Scribd logo
1 de 45
Baixar para ler offline
DELEGATES
Desvendando esse poderoso padrão
na API do iOS
APRESENTAÇÃO
Osni Oliveira
osni.oliveira@caelum.com.br
@osnipso
github.com/osnipso
CONHECIMENTO
• Básico de Objective-C
• Conceitos fundamentais do iOS
• Views
• Actions
• Outlets
slideshare.net/osnipso/primeiros-passos-no-ios-com-objectivec
DELEGATES
• Padrão de Projeto (Design Pattern)
• Divisão de responsabilidades
• Princípio da responsabilidade única
• Comunicação entre objetos
• Inversão de Controle (IoC)
DELEGATES
Colaboração entre objetos
IMPORTÂNCIA
• É *o* padrão mais importante no iOS
• Muito utilizado pela API
• Muito utilizado pelos desenvolvedores
• Imprescindível compreender
• Necessário dominar
• Boa prática utilizar - padronização
DEFINIÇÕES
• Delegation (iOS Developer Library - Cocoa Core
Competencies)
https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/
Delegation.html
• Delegates and Data Sources (iOS Developer Library -
Concepts in Objective-C Programming)
https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/
DelegatesandDataSources/DelegatesandDataSources.html#//apple_ref/doc/uid/TP40010810-CH11
CONCEITO
Apple (Cocoa Core Competencies):
Delegação é um padrão simples e poderoso em que um
objeto em um programa age no lugar de, ou em coordenação
com outro objeto.
(...)
O objeto que delega é tipicamente um objeto do framework e
o delegado é tipicamente um objeto controller customizado.
CONCEITO
Delega
(framework)
Delegado
Mensagem
Protocolo (opcional)
CONCEITO
• Recebe o delegado como
dependência (injeção)
• Faz a “primeira parte” da
tarefa
• Envia a mensagem
Delega
(framework)
CONCEITO
• É injetado para o objeto que
delega
• Garante a implementação
da mensagem
• Faz a “segunda parte” da
tarefa
Delegado
CONCEITO
• Opcional
• Contrato formal
• Acoplamento através do
contrato (leve)
Protocolo
CONCEITO
Dois objetos colaboram para realizar uma tarefa.
O primeiro, faz até onde ele consegue fazer.
O que ele não consegue? Delega para o segundo!
CONCEITO
Delega
(framework)
Delegado
Mensagem
Protocolo (opcional)
EXEMPLO: UIAlertView
(ViewController.h)
@interface ViewController : UIViewController <UIAlertViewDelegate>
(ViewController.m)
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Exemplo 1"
message:@"Começando com delegates"
delegate:self
cancelButtonTitle:@"Cancela"
otherButtonTitles:@"Ok", nil];
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex { ... }
EXEMPLO: UIAlertView
UIAlertView ViewController
alertView:clickedButtonAtIndex:
UIAlertViewDelegate
delegate
referência
EXEMPLO: UIAlertView
• Sabe exibir a mensagem e os botões
• Sabe qual botão foi tocado (“clicado”) pelo usuário
• Não sabe o que fazer a partir desse ponto!
• Depende da aplicação
• Aciona o delegado para fazer
EXEMPLO:
UIImagePickerController
(ViewController.h)
@interface ViewController : UIViewController <UINavigationControllerDelegate,
UIImagePickerControllerDelegate>
(ViewController.m)
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info { ... }
EXEMPLO:
UIImagePickerController
UIImagePickerController ViewController
imagePickerController:didFinishPickingMediaWithInfo:
UINavigationControllerDelegate (*)
UIImagePickerControllerDelegate
delegate
referência
EXEMPLO:
UIImagePickerController
• Sabe exibir a galeria de imagens/vídeos (câmera, etc.)
• Sabe qual image/vídeo foi selecionado pelo usuário
• Não sabe o que fazer a partir desse ponto!
• Depende da aplicação
• Aciona o delegado para fazer
OUTROS EXEMPLOS
• UITableView
• UITableViewDelegate (interação com UI / exibição avançada)
• UITableViewDataSource (exibição básica)
OUTROS EXEMPLOS
• UIApplicationDelegate
(AppDelegate.h)
@interface AppDelegate : UIResponder <UIApplicationDelegate>
E O CONTRATO?
• Acoplamento a um protocolo específico
• Melhor que acoplar diretamente à classe...
• Obrigatoriedade de implementar todas as mensagens (?)
• Péssimo. Implementações vazias, adapters, etc.
EXEMPLO - SEM PROTOCOLO
• UIPickerController, porém
seleciona ao confirmar
• Permite cancelar seleção
• Exibido como modal
EXEMPLO - SEM PROTOCOLO
• MYPickerViewController é quem implementa
UIPickerViewDataSource, UIPickerViewDelegate
(MYPickerViewController.h)
@interface MYPickerViewController : UIViewController <UIPickerViewDataSource,
UIPickerViewDelegate>
• Exibe conteúdo fixo
• Seguindo a mesma idéia, podemos perguntar a um
DataSource o que exibir... (desafio)
EXEMPLO - SEM PROTOCOLO
• Precisamos usar performSelector:
• Delegate pode ser genérico, mas precisa implementar o
protocolo NSObject
(MYPickerViewController.h)
@property (weak, atomic) id<NSObject> delegate;
(MYPickerViewController.m)
if ([self.delegate respondsToSelector:@selector(pickedItem:)]) {
[self.delegate performSelector:@selector(pickedItem:)
withObject:@(self.selectedItem)];
}
EXEMPLO - SEM PROTOCOLO
• Problemas com o compilador:
• Até dá pra desligar esse aviso, mas...
EXEMPLO - SEM PROTOCOLO
MYPickerViewController ViewController
cancelPicking (opcional)
pickedItem: (opcional)
NSObject
delegate
referência
EXEMPLO - SEM PROTOCOLO
Prós:
• Menos trabalho
• Sem implementações
desnecessárias, adapters
Contras:
• Contrato implícito!
• Sem autocomplete
• Sem ajuda do compilador
• Muito limitado!
EXEMPLO - SEM PROTOCOLO
Limitações
• Protocolo NSObject
performSelector:
performSelector:withObject:
performSelector:withObject:withObject:
• Boxing (syntax sugar)
EXEMPLO - COM
PROTOCOLO
(MYPickerViewController.h)
@class MYPickerViewController;
@protocol MYPickerViewControllerDelegate <NSObject>
@optional
- (void)cancelPickerViewController:
(MYPickerViewController *)pickerViewController;
@required
- (void)pickerViewController:(MYPickerViewController *)pickerViewController
pickedItem:(NSInteger)itemIndex;
@end
@property (weak, atomic) id<MYPickerViewControllerDelegate> delegate;
EXEMPLO - COM
PROTOCOLO
(MYPickerViewController.m)
- (IBAction)cancelPicking:(id)sender
{
if ([self.delegate respondsToSelector:
@selector(cancelPickerViewController:)]) {
[self.delegate cancelPickerViewController:self];
}
}
- (IBAction)confirmPicking:(id)sender
{
[self.delegate pickerViewController:self pickedItem:self.selectedItem];
}
EXEMPLO - COM
PROTOCOLO
MYPickerViewController ViewController
cancelPickerViewController: (opcional)
pickerViewController:pickedItem:
MYPickerViewControllerDelegate
delegate
referência
EXEMPLO - COM
PROTOCOLO
Prós:
• Contrato explícito
• Com autocomplete
• Com ajuda do compilador
• Mais flexível e poderoso
Contras:
• Mais trabalho
Com @optional:
• Sem implementações
desnecessárias, adapters
• Continua autocomplete!
EXEMPLO - COM BLOCOS
(MYPickerViewController.h)
@property (copy, atomic) void (^cancelBlock)
(MYPickerViewController *pickerViewController);
@property (copy, atomic) void (^successBlock)
(MYPickerViewController *pickerViewController,
NSInteger itemIndex);
EXEMPLO - COM BLOCOS
(MYPickerViewController.m)
- (IBAction)cancelPicking:(id)sender
{
if (self.cancelBlock) {
self.cancelBlock(self);
}
}
- (IBAction)confirmPicking:(id)sender
{
if (self.successBlock) {
self.successBlock(self, self.selectedItem);
}
}
EXEMPLO - COM BLOCOS
(ViewController.m)
MYPickerViewController *pickerViewController =
[[MYPickerViewController alloc] init];
pickerViewController.cancelBlock =
^(MYPickerViewController *pickerViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
};
pickerViewController.successBlock =
^(MYPickerViewController *pickerViewController, NSInteger itemIndex) {
NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex);
[self dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:pickerViewController animated:YES completion:nil];
EXEMPLO - COM BLOCOS
MYPickerViewController ViewController
void (^cancelBlock)(MYPickerViewController *pickerViewController);
void (^successBlock)(MYPickerViewController *pickerViewController,
NSInteger itemIndex);
Contrato está na assinatura do bloco!
bloco
bloco (cópia)
EXEMPLO - COM BLOCOS
Prós:
• Contrato explícito
• Com ajuda do compilador
• (Ainda) mais flexível e
poderoso
Contras:
• Uma propriedade por
callback
• Sintaxe bizarra!
• Problemas de
gerenciamento de
memória...
EXEMPLO - COM BLOCOS
• Dá pra melhorar um pouquinho a sintaxe...
(MYPickerViewController.h)
typedef void (^MYPickerViewControllerCancelBlock)
(MYPickerViewController *pickerViewController);
typedef void (^MYPickerViewControllerSuccessBlock)
(MYPickerViewController *pickerViewController,
NSInteger itemIndex);
@property (copy, atomic) MYPickerViewControllerCancelBlock cancelBlock;
@property (copy, atomic) MYPickerViewControllerSuccessBlock successBlock;
EXEMPLO - COM BLOCOS
• Cuidado com ciclos de retenção!
MYPickerViewController ViewController
bloco
bloco (cópia de self - “strong”)
picker
pickerViewController (strong)
EXEMPLO - COM BLOCOS
Cuidado:
• Fechamento (closure) no escopo da instância
• Programação funcional - paradigma misto
• Extensão da linguagem C, ainda não padronizada
Curiosidade:
• Sintaxe é a mesma de ponteiro de função (“*” vira “^”)
EXEMPLO - COM BLOCOS
• Resolvendo (possíveis) ciclos de retenção:
(ViewController.m)
typeof(self) __weak weakSelf = self;
pickerViewController.cancelBlock =
^(MYPickerViewController *pickerViewController) {
[weakSelf dismissViewControllerAnimated:YES completion:nil];
};
pickerViewController.successBlock =
^(MYPickerViewController *pickerViewController, NSInteger itemIndex) {
NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex);
[weakSelf dismissViewControllerAnimated:YES completion:nil];
};
DICAS
• Procure entender o conceito (callback...?)
• Observe as APIs e como elas utilizam o padrão
• Na dúvida, implemente com protocolos (tradicional)
• APIs novas usam cada vez mais blocos - tendência
OBRIGADO!
slideshare.net/osnipso/ios-delegates-mobile-conf-rio-2014
github.com/osnipso/mobileconf2014
osni.oliveira@caelum.com.br
@osnipso

Mais conteúdo relacionado

Mais procurados

O que você precisa para iniciar no iOS e Objective-C -
O que você precisa para iniciar no iOS e Objective-C - O que você precisa para iniciar no iOS e Objective-C -
O que você precisa para iniciar no iOS e Objective-C - Fábio Pimentel
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN StackBruno Catão
 
Flask for CMS/App Framework development.
Flask for CMS/App Framework development.Flask for CMS/App Framework development.
Flask for CMS/App Framework development.Bruno Rocha
 
Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014Michael Castillo Granados
 

Mais procurados (7)

O que você precisa para iniciar no iOS e Objective-C -
O que você precisa para iniciar no iOS e Objective-C - O que você precisa para iniciar no iOS e Objective-C -
O que você precisa para iniciar no iOS e Objective-C -
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
Flask for CMS/App Framework development.
Flask for CMS/App Framework development.Flask for CMS/App Framework development.
Flask for CMS/App Framework development.
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
 
Python 07
Python 07Python 07
Python 07
 
Java script aula 05 - funções
Java script   aula 05 - funçõesJava script   aula 05 - funções
Java script aula 05 - funções
 
Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014
 

Destaque

Destaque (20)

Proyecto CPE - Cruz de Piedra
Proyecto CPE - Cruz de PiedraProyecto CPE - Cruz de Piedra
Proyecto CPE - Cruz de Piedra
 
Atividades relativas ao livro 05 1ª etapa
Atividades relativas ao livro 05 1ª etapaAtividades relativas ao livro 05 1ª etapa
Atividades relativas ao livro 05 1ª etapa
 
Laevaluacion
LaevaluacionLaevaluacion
Laevaluacion
 
Tarea tere
Tarea tereTarea tere
Tarea tere
 
Sinqueb
SinquebSinqueb
Sinqueb
 
Siiub
SiiubSiiub
Siiub
 
Presentación antonio
Presentación antonioPresentación antonio
Presentación antonio
 
Jessik 1103
Jessik 1103Jessik 1103
Jessik 1103
 
Ram
RamRam
Ram
 
Artesanias
ArtesaniasArtesanias
Artesanias
 
DIA INTERNACIONAL DEL AGUA
DIA INTERNACIONAL DEL AGUADIA INTERNACIONAL DEL AGUA
DIA INTERNACIONAL DEL AGUA
 
Tratado da verdadeira devoção à Santissima Virgem Maria - São Luis Maria Gri...
Tratado da verdadeira devoção à Santissima Virgem Maria -  São Luis Maria Gri...Tratado da verdadeira devoção à Santissima Virgem Maria -  São Luis Maria Gri...
Tratado da verdadeira devoção à Santissima Virgem Maria - São Luis Maria Gri...
 
Trabajo
TrabajoTrabajo
Trabajo
 
matematica
matematicamatematica
matematica
 
Para blog
Para blogPara blog
Para blog
 
Unidad 0 y 1
Unidad 0 y 1Unidad 0 y 1
Unidad 0 y 1
 
Ana . Tintín en el Tibet
Ana . Tintín en el TibetAna . Tintín en el Tibet
Ana . Tintín en el Tibet
 
Ginecología
GinecologíaGinecología
Ginecología
 
Renderpixel - Exclusivamente Render's
Renderpixel - Exclusivamente Render'sRenderpixel - Exclusivamente Render's
Renderpixel - Exclusivamente Render's
 
Trabajo psico 3 evaluación
Trabajo psico 3 evaluaciónTrabajo psico 3 evaluación
Trabajo psico 3 evaluación
 

Semelhante a iOS Delegates - Mobile Conf Rio 2014

Desenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-TouchDesenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-TouchCampus Party Brasil
 
Aula02 android hands_on
Aula02 android hands_onAula02 android hands_on
Aula02 android hands_onRoberson Alves
 
Seminário sd android_exemplos
Seminário sd android_exemplosSeminário sd android_exemplos
Seminário sd android_exemplosCalvin Rodrigues
 
Desenvolvimento de aplicativos Móveis com IONIC
Desenvolvimento de aplicativos Móveis com IONICDesenvolvimento de aplicativos Móveis com IONIC
Desenvolvimento de aplicativos Móveis com IONICGisely Lucas
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeRafael Benevides
 
Material Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu AppMaterial Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu Appalissin
 
JHipster - Produtividade e Maturidade em suas mãos
JHipster - Produtividade e Maturidade em suas mãosJHipster - Produtividade e Maturidade em suas mãos
JHipster - Produtividade e Maturidade em suas mãosThiago Soares
 
Minicurso Objective-C
Minicurso Objective-CMinicurso Objective-C
Minicurso Objective-CSaulo Arruda
 
Angular 2, TypeScript e Além
Angular 2, TypeScript e AlémAngular 2, TypeScript e Além
Angular 2, TypeScript e AlémAndre Baltieri
 
Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Giovanni Bassi
 
365on Lab Asp.Net MVC Fundamentos 01 Overview
365on Lab Asp.Net MVC Fundamentos 01 Overview365on Lab Asp.Net MVC Fundamentos 01 Overview
365on Lab Asp.Net MVC Fundamentos 01 OverviewAlexsandro Almeida
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifaguestea329c
 

Semelhante a iOS Delegates - Mobile Conf Rio 2014 (20)

Desenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-TouchDesenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-Touch
 
Caelum Day In Rio
Caelum Day In RioCaelum Day In Rio
Caelum Day In Rio
 
Desenvolvimento iOS
Desenvolvimento iOSDesenvolvimento iOS
Desenvolvimento iOS
 
Aula02 android hands_on
Aula02 android hands_onAula02 android hands_on
Aula02 android hands_on
 
Seminário sd android_exemplos
Seminário sd android_exemplosSeminário sd android_exemplos
Seminário sd android_exemplos
 
Como fazer boas libs
Como fazer boas libs Como fazer boas libs
Como fazer boas libs
 
Desenvolvimento de aplicativos Móveis com IONIC
Desenvolvimento de aplicativos Móveis com IONICDesenvolvimento de aplicativos Móveis com IONIC
Desenvolvimento de aplicativos Móveis com IONIC
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpike
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Material Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu AppMaterial Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu App
 
JHipster - Produtividade e Maturidade em suas mãos
JHipster - Produtividade e Maturidade em suas mãosJHipster - Produtividade e Maturidade em suas mãos
JHipster - Produtividade e Maturidade em suas mãos
 
Mobile conf
Mobile confMobile conf
Mobile conf
 
Minicurso Objective-C
Minicurso Objective-CMinicurso Objective-C
Minicurso Objective-C
 
Angular 2, TypeScript e Além
Angular 2, TypeScript e AlémAngular 2, TypeScript e Além
Angular 2, TypeScript e Além
 
Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2
 
Kotlin first
Kotlin firstKotlin first
Kotlin first
 
365on Lab Asp.Net MVC Fundamentos 01 Overview
365on Lab Asp.Net MVC Fundamentos 01 Overview365on Lab Asp.Net MVC Fundamentos 01 Overview
365on Lab Asp.Net MVC Fundamentos 01 Overview
 
Curso AngularJS - Parte 1
Curso AngularJS - Parte 1Curso AngularJS - Parte 1
Curso AngularJS - Parte 1
 
Python 06
Python 06Python 06
Python 06
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifa
 

iOS Delegates - Mobile Conf Rio 2014

  • 1. DELEGATES Desvendando esse poderoso padrão na API do iOS
  • 3. CONHECIMENTO • Básico de Objective-C • Conceitos fundamentais do iOS • Views • Actions • Outlets slideshare.net/osnipso/primeiros-passos-no-ios-com-objectivec
  • 4. DELEGATES • Padrão de Projeto (Design Pattern) • Divisão de responsabilidades • Princípio da responsabilidade única • Comunicação entre objetos • Inversão de Controle (IoC)
  • 6. IMPORTÂNCIA • É *o* padrão mais importante no iOS • Muito utilizado pela API • Muito utilizado pelos desenvolvedores • Imprescindível compreender • Necessário dominar • Boa prática utilizar - padronização
  • 7. DEFINIÇÕES • Delegation (iOS Developer Library - Cocoa Core Competencies) https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/ Delegation.html • Delegates and Data Sources (iOS Developer Library - Concepts in Objective-C Programming) https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ DelegatesandDataSources/DelegatesandDataSources.html#//apple_ref/doc/uid/TP40010810-CH11
  • 8. CONCEITO Apple (Cocoa Core Competencies): Delegação é um padrão simples e poderoso em que um objeto em um programa age no lugar de, ou em coordenação com outro objeto. (...) O objeto que delega é tipicamente um objeto do framework e o delegado é tipicamente um objeto controller customizado.
  • 10. CONCEITO • Recebe o delegado como dependência (injeção) • Faz a “primeira parte” da tarefa • Envia a mensagem Delega (framework)
  • 11. CONCEITO • É injetado para o objeto que delega • Garante a implementação da mensagem • Faz a “segunda parte” da tarefa Delegado
  • 12. CONCEITO • Opcional • Contrato formal • Acoplamento através do contrato (leve) Protocolo
  • 13. CONCEITO Dois objetos colaboram para realizar uma tarefa. O primeiro, faz até onde ele consegue fazer. O que ele não consegue? Delega para o segundo!
  • 15. EXEMPLO: UIAlertView (ViewController.h) @interface ViewController : UIViewController <UIAlertViewDelegate> (ViewController.m) UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Exemplo 1" message:@"Começando com delegates" delegate:self cancelButtonTitle:@"Cancela" otherButtonTitles:@"Ok", nil]; - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { ... }
  • 17. EXEMPLO: UIAlertView • Sabe exibir a mensagem e os botões • Sabe qual botão foi tocado (“clicado”) pelo usuário • Não sabe o que fazer a partir desse ponto! • Depende da aplicação • Aciona o delegado para fazer
  • 18. EXEMPLO: UIImagePickerController (ViewController.h) @interface ViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate> (ViewController.m) UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; imagePicker.delegate = self; [self presentViewController:imagePicker animated:YES completion:nil]; - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { ... }
  • 20. EXEMPLO: UIImagePickerController • Sabe exibir a galeria de imagens/vídeos (câmera, etc.) • Sabe qual image/vídeo foi selecionado pelo usuário • Não sabe o que fazer a partir desse ponto! • Depende da aplicação • Aciona o delegado para fazer
  • 21. OUTROS EXEMPLOS • UITableView • UITableViewDelegate (interação com UI / exibição avançada) • UITableViewDataSource (exibição básica)
  • 22. OUTROS EXEMPLOS • UIApplicationDelegate (AppDelegate.h) @interface AppDelegate : UIResponder <UIApplicationDelegate>
  • 23. E O CONTRATO? • Acoplamento a um protocolo específico • Melhor que acoplar diretamente à classe... • Obrigatoriedade de implementar todas as mensagens (?) • Péssimo. Implementações vazias, adapters, etc.
  • 24. EXEMPLO - SEM PROTOCOLO • UIPickerController, porém seleciona ao confirmar • Permite cancelar seleção • Exibido como modal
  • 25. EXEMPLO - SEM PROTOCOLO • MYPickerViewController é quem implementa UIPickerViewDataSource, UIPickerViewDelegate (MYPickerViewController.h) @interface MYPickerViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> • Exibe conteúdo fixo • Seguindo a mesma idéia, podemos perguntar a um DataSource o que exibir... (desafio)
  • 26. EXEMPLO - SEM PROTOCOLO • Precisamos usar performSelector: • Delegate pode ser genérico, mas precisa implementar o protocolo NSObject (MYPickerViewController.h) @property (weak, atomic) id<NSObject> delegate; (MYPickerViewController.m) if ([self.delegate respondsToSelector:@selector(pickedItem:)]) { [self.delegate performSelector:@selector(pickedItem:) withObject:@(self.selectedItem)]; }
  • 27. EXEMPLO - SEM PROTOCOLO • Problemas com o compilador: • Até dá pra desligar esse aviso, mas...
  • 28. EXEMPLO - SEM PROTOCOLO MYPickerViewController ViewController cancelPicking (opcional) pickedItem: (opcional) NSObject delegate referência
  • 29. EXEMPLO - SEM PROTOCOLO Prós: • Menos trabalho • Sem implementações desnecessárias, adapters Contras: • Contrato implícito! • Sem autocomplete • Sem ajuda do compilador • Muito limitado!
  • 30. EXEMPLO - SEM PROTOCOLO Limitações • Protocolo NSObject performSelector: performSelector:withObject: performSelector:withObject:withObject: • Boxing (syntax sugar)
  • 31. EXEMPLO - COM PROTOCOLO (MYPickerViewController.h) @class MYPickerViewController; @protocol MYPickerViewControllerDelegate <NSObject> @optional - (void)cancelPickerViewController: (MYPickerViewController *)pickerViewController; @required - (void)pickerViewController:(MYPickerViewController *)pickerViewController pickedItem:(NSInteger)itemIndex; @end @property (weak, atomic) id<MYPickerViewControllerDelegate> delegate;
  • 32. EXEMPLO - COM PROTOCOLO (MYPickerViewController.m) - (IBAction)cancelPicking:(id)sender { if ([self.delegate respondsToSelector: @selector(cancelPickerViewController:)]) { [self.delegate cancelPickerViewController:self]; } } - (IBAction)confirmPicking:(id)sender { [self.delegate pickerViewController:self pickedItem:self.selectedItem]; }
  • 33. EXEMPLO - COM PROTOCOLO MYPickerViewController ViewController cancelPickerViewController: (opcional) pickerViewController:pickedItem: MYPickerViewControllerDelegate delegate referência
  • 34. EXEMPLO - COM PROTOCOLO Prós: • Contrato explícito • Com autocomplete • Com ajuda do compilador • Mais flexível e poderoso Contras: • Mais trabalho Com @optional: • Sem implementações desnecessárias, adapters • Continua autocomplete!
  • 35. EXEMPLO - COM BLOCOS (MYPickerViewController.h) @property (copy, atomic) void (^cancelBlock) (MYPickerViewController *pickerViewController); @property (copy, atomic) void (^successBlock) (MYPickerViewController *pickerViewController, NSInteger itemIndex);
  • 36. EXEMPLO - COM BLOCOS (MYPickerViewController.m) - (IBAction)cancelPicking:(id)sender { if (self.cancelBlock) { self.cancelBlock(self); } } - (IBAction)confirmPicking:(id)sender { if (self.successBlock) { self.successBlock(self, self.selectedItem); } }
  • 37. EXEMPLO - COM BLOCOS (ViewController.m) MYPickerViewController *pickerViewController = [[MYPickerViewController alloc] init]; pickerViewController.cancelBlock = ^(MYPickerViewController *pickerViewController) { [self dismissViewControllerAnimated:YES completion:nil]; }; pickerViewController.successBlock = ^(MYPickerViewController *pickerViewController, NSInteger itemIndex) { NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex); [self dismissViewControllerAnimated:YES completion:nil]; }; [self presentViewController:pickerViewController animated:YES completion:nil];
  • 38. EXEMPLO - COM BLOCOS MYPickerViewController ViewController void (^cancelBlock)(MYPickerViewController *pickerViewController); void (^successBlock)(MYPickerViewController *pickerViewController, NSInteger itemIndex); Contrato está na assinatura do bloco! bloco bloco (cópia)
  • 39. EXEMPLO - COM BLOCOS Prós: • Contrato explícito • Com ajuda do compilador • (Ainda) mais flexível e poderoso Contras: • Uma propriedade por callback • Sintaxe bizarra! • Problemas de gerenciamento de memória...
  • 40. EXEMPLO - COM BLOCOS • Dá pra melhorar um pouquinho a sintaxe... (MYPickerViewController.h) typedef void (^MYPickerViewControllerCancelBlock) (MYPickerViewController *pickerViewController); typedef void (^MYPickerViewControllerSuccessBlock) (MYPickerViewController *pickerViewController, NSInteger itemIndex); @property (copy, atomic) MYPickerViewControllerCancelBlock cancelBlock; @property (copy, atomic) MYPickerViewControllerSuccessBlock successBlock;
  • 41. EXEMPLO - COM BLOCOS • Cuidado com ciclos de retenção! MYPickerViewController ViewController bloco bloco (cópia de self - “strong”) picker pickerViewController (strong)
  • 42. EXEMPLO - COM BLOCOS Cuidado: • Fechamento (closure) no escopo da instância • Programação funcional - paradigma misto • Extensão da linguagem C, ainda não padronizada Curiosidade: • Sintaxe é a mesma de ponteiro de função (“*” vira “^”)
  • 43. EXEMPLO - COM BLOCOS • Resolvendo (possíveis) ciclos de retenção: (ViewController.m) typeof(self) __weak weakSelf = self; pickerViewController.cancelBlock = ^(MYPickerViewController *pickerViewController) { [weakSelf dismissViewControllerAnimated:YES completion:nil]; }; pickerViewController.successBlock = ^(MYPickerViewController *pickerViewController, NSInteger itemIndex) { NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex); [weakSelf dismissViewControllerAnimated:YES completion:nil]; };
  • 44. DICAS • Procure entender o conceito (callback...?) • Observe as APIs e como elas utilizam o padrão • Na dúvida, implemente com protocolos (tradicional) • APIs novas usam cada vez mais blocos - tendência