Extensão de ANSI C
• Convenção sintática para definição de classes
• Convenção para métodos de classe e instância
• Sintaxe para chamada de método (mensagem)
• Sintaxe para declaração de propriedades
• Convenção para tipagem estática e dinâmica
• Blocos - segmentos de código encapsulados
• Extensões da linguagem como protocolos e
categorias
Vantagens
• Tipagem dinâmica detemina classe em
tempo de execução.
• Ligação dinâmica determina o método a ser
chamado em tempo de execução.
• Carregamento dinâmico permite adicionar
módulos de código em tempo de execução.
id
• Objetos são um tipo de dados distinto: id
typedef struct objc_object {
Class isa;
} *id;
Dynamic Typing
Objetos são tipados dinamicamente
em tempo de execução.
id myObject;
É possível também informar ao compilador a
classe do objeto estaticamente informando a
classe no código fonte.
Rectangle* myObject;
Object Messaging
• Para fazer alguma coisa com um objeto,
você envia uma mensagem para ele
solicitando para executar um método.
[receiver message];
[myRectangle display];
[myRectangle setWidth:2.0];
[myRectangle setOriginX: 30.0 y: 50.0];
[receiver makeGroup:group, memberOne, memberTwo,
memberThree];
[myRectangle setPrimaryColor:[otherRect primaryColor]];
Messages to nil
• Enviar uma mensagem para um objeto nil
não tem nenhum efeito em tempo de
execução.
id anObjectMaybeNil = nil;
// this is valid
if ([anObjectMaybeNil methodThatReturnsADouble]
== 0.0)
{
// implementation continues...
}
Dynamic Binding
• Ao enviar uma mensagem à um objeto, o
método que será chamado é determinado
em tempo de execução.
Dot sintax
• Notação usando ponto (.) como alternativa
aos colchetes ([]) para invocar métodos de
acesso à propriedades.
myInstance.value = 10; [myInstance setValue:10];
self.age = 10; [self setAge:10];
x = person.address.street.name; x = [[[person address] street]
name];
Classes
• A definição de classe é um protótipo para
um tipo de objeto;
• O compilador cria um único objeto para
cada classe que sabe como criar outros
objetos (factory object)
• Este objeto constrói instâncias da classe.
Herança
NSObject
Graphic
Text Text
Shape
Line Rectangle
NSObject
• É uma classe raiz e não tem uma
superclasse.
• Define um framework básico para objetos
Objective-C e interação entre eles.
Herdando variáveis de
instância e métodos
• Quando um objeto de classe cria uma nova
instância, o novo objeto contém as variáveis
de instância e métodos definidos pela
classe assim como de suas superclasses.
Sobrescrevendo
métodos
• Envio de mensagens para self e super
para referenciar respectivamente métodos
da classe atual e das superclasses.
Static Typing
• Você pode usar o nome da classe no lugar
de id para designar o tipo do objeto
Rectangle* myRectangle;
Type Introspection
• Instâncias podem consultar seu tipo em
tempo de execução:
if ( [anObject isMemberOfClass:someClass] )
...
if ( [anObject isKindOfClass:someClass] )
...
Class Objects
• O objeto da classe contêm:
• Nome da classe e sua superclasse
• Modelo das variáveis de instância
• Declaração dos métodos seu retorno e
seus argumentos
• Implementação dos métodos
Class Objects
• Todos os objetos de classe são do tipo
Class
Class aClass = [anObject class];
Class rectClass = [Rectangle class];
Criando instâncias
• A principal função do objeto da classe é
criar instâncias
Rectangle* myRectangle =
[[Rectangle alloc] init];
Rectangle* myRectangle =
[[Rectangle alloc]
initWithSize:CGSize(800, 600)];
Variáveis
• Para todas as instâncias da classe acessarem
uma variável, você deve defini-la
externamente.
static MyClass *MCLSSharedInstance;
@implementation MyClass
+ (MyClass *)sharedInstance
{
// check for existence of shared instance
return MCLSSharedInstance;
}
Inicializando objetos de
classe
• O método initialize é chamado antes da
criação da primeira instância da classe.
+ (void)initialize
{
if (self == [ThisClass class]) {
// Perform initialization here.
...
}
}
Definindo uma Classe
• Em Objective-C classes são definidas em
duas partes:
• Uma interface que declara os métodos
e propriedades;
• Uma implementação que contém o
código que implementa seus métodos.
Arquivos de código-
fonte
Extensão Tipo
Header files da definição de classes,
.h
tipos, funções e constantes.
Source files da implementação em
.m
Objective-C ou C
Source files da imeplementação em C++
.mm
além de Objective-C e C
Class Interface
• A declaração da interface da classe inicia
com a diretiva @interface e termina
com a diretiva @end
@interface ClassName : ItsSuperclass
// Method and property declarations.
@end
Instance methods
• Marcado com um sinal menos (-), o tipo de
retorno é opcional (usado id caso não
informado), parâmetros são separados por
dois pontos (:)
- (void)display;
- (float)radius;
- (void)setRadius:(float)aRadius;
- (void)setWidth:(float)width
height:(float)height;
- makeGroup:group, ...;
Class methods
• Segue a mesma convenção dos métodos de
instância, mas são marcadas com o sinal
mais (+)
+ (MyClass*)sharedInstance;
+ (MyClass*)objectWithWidth:(float)width
height:(float)height;
Importando a interface
• O arquivo de interface pode ser importado
em qualquer outro arquivo fonte.
#import "Rectangle.h"
Referindo-se à outras
classes
• Quando uma classe ainda não foi definida
mas precisa ser referenciada você pode
mencioná-la com a diretiva @class
@class Rectangle, Circle;
Class Implementation
• Começa com a diretiva
@implementation e termina com a
diretiva @end
@implementation ClassName
{
// Instance variable declarations.
}
// Method definitions.
@end
Using super
• O método init é pensado para funcionar
desta forma:
- (id)init {
self = [super init];
if (self) {
...
}
return self;
}
Protocolos
• Protocolos definem métodos que podem
ser implementados por qualquer classe. São
úteis para:
• Declarar métodos que espera que outra
classe implementa;
• Declarar uma interface escondendo sua
classe;
• Capturar similaridades sem relação
hierárquica
Protocolos Informais
• Agrupando métodos em uma declaração de
categoria
@interface NSObject ( MyXMLSupport )
- initFromXMLRepresentation:(NSXMLElement
*)XMLElement;
- (NSXMLElement *)XMLRepresentation;
@end
Implementando um
Protocolo
• Uma classe diz que adota um protocolo
formal indicando os protocolos entre
símbolos maior e menor (<>)
@interface ClassName : ItsSuperclass <
protocol list >
@interface ClassName ( CategoryName ) <
protocol list >
@interface Formatter : NSObject < Formatting,
Prettifying >
Conformidade com um
protocolo
• É possível verificar se um objeto está em
conformidade com um protocolo
if (![receiver
conformsToProtocol:@protocol(MyXMLSupport)]) {
// Object does not conform to MyXMLSupport
protocol
// If you are expecting receiver to
implement methods declared in the MyXMLSupport
protocol, this is probably an error
}
Type Checking
• Em uma declaração de tipo, os protocolos
são listados entre símbolos maior e menor
(<>)
- (id <Formatting>)formattingService;
Formatter<Formatting> *anObject;
id <MyXMLSupport> anObject;
Propriedades
• Tipicamente métodos de acesso à
propriedades do objeto são um par de
getters e setters. Propriedades oferecem:
• Uma especificação explícita de como os
métodos de acesso se comportam;
• O compilador pode criar esses métodos;
• Propriedades são identificadas
sintaticamente, o compilador dectecta
caso elas não existam;
Declaração de
propriedades
• Usando a diretiva @property
@property (attributes) type name;
@interface MyClass : NSObject
@property float value;
@end
// É equivalente à:
- (float)value;
- (void)setValue:(float)newValue;
Implementação da
propriedade
• Usar @synthesize ou @dynamic no
bloco @implementation
@interface MyClass : NSObject
@property(copy, readwrite) NSString *value;
@end
@implementation MyClass
@synthesize value = _value;
@end
Categorias e extensões
• Uma categoria permite adicionar métodos
à classes existentes.
#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end
Fast Enumeration
• Sintaxe para enumerar o conteúdo de
coleções
for ( Type newVariable in expression )
{ statements }
NSArray *array = [NSArray arrayWithObjects:
@"one", @"two", @"three", @"four",
nil];
for (NSString *element in array) {
NSLog(@"element: %@", element);
}
Selectors
• Em Objective-C selectors tem dois
sentidos:
• Pode ser usado para simplesmente
referenciar um método;
• Pode ser um identificador único que
substitui o nome após a compilação;
Métodos e selectors
SEL setWidthHeight;
setWidthHeight =
@selector(setWidth:height:);
setWidthHeight =
NSSelectorFromString(aBuffer);
NSString *method;
method =
NSStringFromSelector(setWidthHeight);
Variável para a chamada
do método
[friend
performSelector:@selector(gossipAbout:)
withObject:aNeighbor];
// É equivalente à:
[friend gossipAbout:aNeighbor];
id helper = getTheReceiver();
SEL request = getTheSelector();
[helper performSelector:request];
Evitando erros
if ( [anObject
respondsToSelector:@selector(setOrigin::)]
)
[anObject setOrigin:0.0 :0.0];
else
fprintf(stderr, "%s can’t be placed
n", [NSStringFromClass([anObject class])
UTF8String]);