SlideShare uma empresa Scribd logo
1 de 52
Baixar para ler offline
Programação Orientada a Objectos
      (OOP) - Parte 2: ObjC
     Cursos de Verão na Católica 2010




        Jorge C. S. Cardoso, Luís Gustavo Martins
      jorgecardoso@ieee.org, lmartins@porto.ucp.pt
Classe Veículo em ObjC
 Divisão do código em duas partes:

     1. Interface
          ■ declarada num ficheiro Veiculo.h

     2. Implementação
         ■ definida num ficheiro Veiculo.m




    http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
Classe Veículo em ObjC
                                               #import <Foundation/Foundation.h>
 Interface - Veiculo.h
                                               @interface Veiculo : NSObject {
                                                  // instance variables
                                                  int velMax;
                                                  int velActual;
                                                  int numRodas;
                                                  int numLugares;
                                               }
                                               //setters and getters
 O ObjC "obriga" ao uso de getters e setters   - (void) setVelMax: (int)vel;
                                               - (int) velMax;
                                               - (void) setVelActual: (int)vel;
   --> Encapsulamento!                         - (int) velActual;
                                               - (void) setNumRodas: (int)numRodas;
                                               - (int) numRodas;
                                               - (void) setNumLugares: (int)numLugares;
                                               - (int) numLugares;
                                               // other method declarations
                                               - (void) arrancar;
                                               - (void) travar;
                                               - (void) acelerar;
                                               - (void) buzinar;
                                               - (BOOL) estaParado;
                                               - (void) mostrarEstado;
                                               @end
Classe Veículo em ObjC
 Implementação - Veiculo.m
 #import "Veiculo.h"

 @implementation Veiculo

 //setter and getters
 -(int)velMax {
     return velMax;
 }
 -(void) setVelMax: (int)vel {
     velMax = vel;                            ● Implementar setters/getters
 }
 //... similar for other setter/getters       ● Implementar métodos
 //other methods
 -(void) arrancar {
                                            Getters e setters podem ser
    //implementação do método arrancar...   criados automaticamente...
 }                                             - properties
 -(void) travar {                              - synthesize
    // ...
 }

 //... other methods...

 @end
Classe Veículo em ObjC
     Uso de Properties e Synthesized Getters e Setters
#import <Foundation/Foundation.h>
                                           #import <Foundation/Foundation.h>
@interface Veiculo : NSObject {
   // instance variables                   @interface Veiculo : NSObject {
   int velMax;                                // instance variables
   int velActual;                             int velMax;
   int numRodas;                              int velActual;
   int numLugares;                            int numRodas;
}                                             int numLugares;
//setters and getters                      }
- (void) setVelMax: (int)vel;              //properties
- (int) velMax;                            @property velMax;
- (void) setVelActual: (int)vel;           @property velActual;
- (int) velActual;                         @property numRodas, numLugares;
- (void) setNumRodas: (int)numRodas;
- (int) numRodas;                          // other method declarations
- (void) setNumLugares: (int)numLugares;   - (void) arrancar;
- (int) numLugares;                        - (void) travar;
// other method declarations               - (void) acelerar;
- (void) arrancar;                         - (void) buzinar;
- (void) travar;                           - (BOOL) estaParado;
- (void) acelerar;                         - (void) mostrarEstado;
- (void) buzinar;                          @end
- (BOOL) estaParado;
- (void) mostrarEstado;
@end
Classe Veículo em ObjC
    Uso de Properties e Synthesized Getters e Setters
#import "Veiculo.h"                        #import "Veiculo.h"

@implementation Veiculo                    @implementation Veiculo

//setter and getters                       //synthesized setter and getters
-(int)velMax {                             @synthesize velMax;
    return velMax;                         @synthesize velActual:
}                                          @synthesize numRodas;
-(void) setVelMax: (int)vel {              @synthesize numLugares;
    velMax = vel;
}                                          //other methods
//... similar for other setter/getters     -(void) arrancar {
                                              //implementação do método arrancar...
//other methods                            }
-(void) arrancar {
   //implementação do método arrancar...   -(void) travar {
}                                             // ...
                                           }
-(void) travar {
   // ...                                  //... other methods...
}
                                           @end
//... other methods...

@end
Classe Veículo em ObjC
   Uso de Properties e Synthesized Getters e Setters
       ● É possível alterar o comportamento do setter sintetizado para uma
         variável membra, usando modificadores

Num setter do tipo:

  -(void) setVar: (SomeClass *)value

Se o sintetizarmos com os seguintes modificadores, teremos no corpo do setter (sintetizado) as seguintes atribuições:

  @property (assign) var

  var = value; //simple assignation

 @property (retain) var

  var = [value retain]; //assignation with reference counter increment

 @property (copy) var

  var = [value copy]; //object is copied (must conform to the NSCopying protocol...)
Herança em ObjC
● O ObjC suporta herança simples
   ○ ou seja, uma classe apenas pode herdar de uma classe pai
       ■ Tal como o Java (outras linguagens, como o C++, suportam herança
         múltipla)
   ○ Em vez de herança multipla, o ObjC suposta o uso de "categories" e
     "protocols" (semelhantes às "interfaces" do Java)
       ■ http://developer.apple.
         com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocCategories.html
       ■ http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocProtocols.
         html#//apple_ref/doc/uid/TP30001163-CH15-SW1




      http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: Métodos de Classe e de Instância
 ● Instâncias respondem a métodos de instância:
 - (id) init;
 - (void) setVelMax: (int) vel;
 - (int) velMax;
 - (void) travar;
 ...

 ● Classes respondem a métodos de classe:
 + (id) alloc;
 + (id) Veiculo;
 + (Veiculo *) sharedVeiculo;
 ...
ObjC: Mensagens para Objectos
 ● Em ObjC, em vez de se "chamar" métodos de objectos
   (como em Java ou C++), enviam-se "mensagens"

    ○ Sintaxe:        [receiver message]

          [receiver message:argument]

         [receiver message:arg1 andArg:arg2]

 ● Exemplos:
               Veiculo *meuVeiculo; //assume this exists...

               [meuVeiculo trava];

               [meuVeiculo setVelMax:300] //you wish!! ;-)
               [meuVeiculo vira:90 andPiscaPisca:YES];

               int speed = [meuVeiculo velActual];
ObjC: Mensagens para Objectos
 ● O "Dot-Syntax"

    ○ O ObjC 2.0 introduziu uma outra forma de se aceder a variáveis
      membras de um objecto

            Veiculo *meuVeiculo; //assume this exists...

            int speed1 = [meuVeiculo velActual]; //message
            int speed2 = meuVeiculo.velActual; //dot syntax

            [meuVeiculo setVelActual: 120]; //message
            meuVeiculo.velActual = 60; //dot syntax



    ○ O dot-syntax faz uso dos setters e getters!!
        ■ Não quebra o ENCAPSULAMENTO!!
ObjC: Mensagens para Objectos
 ● O "Dot-Syntax" - Um problema frequente...
     ○ O que é que acontece quando o seguinte código executa?

         @implementation Person
  - (void)setAge:(int)newAge { //setter
     self.age = newAge; //age é uma variável membra
  }
  @end

     ○ É equivalente a:
  @implementation Person
   - (void)setAge:(int)newAge { //setter
     [self setAge:newAge]; // Infinite loop!
  }
  @end
ObjC: self e super
 ● self - mensagens para o próprio Objecto
             #import "Veiculo.h"

             @implementation Veiculo

             -(BOOL) isFamilyVehicle {
                return ([self numLugares] >= 4);
             }

             //other method implementations...


 ● super - mensagens para o "pai" do Objecto
  -(void) doSomething {
     //call superclass implementation first...
     [super doSomething];

      //now do our own stuff...
      int foo = bar;
      //...
  }
ObjC: tipos dinâmicos e estáticos
 ● Objectos com tipos dinâmicos
    ○ id anObject;
       ■ apenas id e não id*
           ■ a não ser que se saiba o que se está a fazer...
       ■ tipo genérico: pode ser usado para apontar para qualquer
         objecto

 ● Objectos com tipos estáticos

    ○ Veiculo *meuVeiculo;

 ● O ObjC implementa verificação de tipos em compile-time (e
   não em run-time)

 ● O ObjC usa sempre "dynamic binding"
ObjC: ciclo de vida de objectos
 ● Criação de Objectos
         ○ Processo de dois passos:
                ■ alocar memória para o objecto: +alloc
                ■ inicializar o estado do objecto: -init
                    ■ Construtor
                                                       Veiculo *meuVeiculo = nil;
#import "Veiculo.h"                                    meuVeiculo = [[Veiculo alloc] init];

@implementation Veiculo

-(id)init {
   // allow superclass to initialize its state first
   if (self = [super init]) {
      velMax = 120;
      velActual = 0;
      numRodas = 4;
      numLugares = 4;
   }
   return self;
}
@end
ObjC: ciclo de vida de objectos
  ● Criação de Objectos - Métodos init (construtores)

        ○ Uma classe pode definir múltiplos métods init
              ■ -(id) init;
              ■ -(id) initWithVelMax:(int) vel;
              ■ -(id) initWithVelMax:(int) vel velActual:(int) vel;
              ■ ...

        ○ Métodos menos específicos chamam tipicamente métodos
          mais específicos usando valores por omissão:

-(id) init {return [self initWithVelMax: 120];}

-(id) initWithVelMax:(int) vel {
   return [self initWithVelMax:vel velActual:0];
}
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos

    ○ Depois de criado com com alloc (normalmente seguido de init),
      e no caso de não mais ser necessário, um objecto deve ser
      "limpo" da memória!

       ■ Para cada alloc deverá haver um dealloc
           ■ caso contrário criam-se "fugas de memória"!!

       ■ No entanto, dealloc nunca é chamado directamente!
           ■ com uma excepção (ver mais à frente...)
           ■ existe um mecanismo para "desalocar" sem chamar dealloc ...
           ■ REFERENCE COUNTING
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos

    ○ REFERENCE COUNTING

       ■ Todos os objectos implementam um "retain count"
           ■ Herdado de NSObject
           ■ enquanto o "retain count" > 0, objectivo é mantido em
             memória e válido

       ■ +alloc e -copy criam objectos com "retain count" == 1
       ■ -retain incrementa o "retain count"
       ■ -release decrementa o "retain count"

       ■ Quando o "retain count" atinge o valor 0 o objecto é destruído!
           ■ -dealloc é chamado automaticamente
           ■ Ponto de não retorno!
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos - REFERENCE COUNTING




       http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos

       Veiculo *meuVeiculo = nil;

       meuVeiculo = [[Veiculo alloc] init];

       [meuVeiculo setVelMax:120];
       [meuVeiculo arranca];
       [meuVeículo setVelActual: 50];
       //...
       [meuVeiculo para];

       //no more need for this object...
       [meuVeiculo release];

       //meuVeiculo will be destroyed in case its retain
       //count is zero (i.e. no one else is pointing to it)
       //And in that case, sending messages to it will CRASH!
       [meuVeiculo arranca];//CRASH!!
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos
     Veiculo *meuVeiculo = nil;

     meuVeiculo = [[Veiculo alloc] init];

     [meuVeiculo setVelMax:120];
     [meuVeiculo arranca];
     [meuVeículo setVelActual: 50];
     //...
     [meuVeiculo para];

     //no more need for this object...
     [meuVeiculo release];

     meuVeiculo = nil; //good programming practice!

     [meuVeiculo arranca];//No longer crashes!:-) No effect...
ObjC: ciclo de vida de objectos
 ● Destruição de Objectos - Destrutor
    ○ Implementação do método -dealloc
     #import "Veiculo.h"

     @implementation Veiculo

     -dealloc { //this is an override of NSObject dealloc
       //do any cleanup that is necessary...
       //...

         //when done, ask super to also clean itself up
         [super dealloc]; //only time you call dealloc explicitly!
     }

     //other method implementations...

     @end
ObjC: a classe NSString
● Suporte genérico para strings Unicode
   ○ Unicode é um sistema de codificação de caracteres que suporta todas
     as linguagens do mundo

● Consistentemente usada na API Cocoa e Cocoa Touch
   ○ em prejuízo das C-strings (i.e. char *)
   ○ sem dúvida uma das classes mais usadas em Cocoa

● Em ObjC, "constant strings" são definidas como:

  @“just as simple”

● E "constant strings" são na realidade instâncias de NSString

     NSString *aString = @”Hello World!”;
ObjC: a classe NSString
● Formatação de Strings
      ○ Semelhante ao usado em Java e C++ (e.g. printf)
            ■ %d - para ints
            ■ %f - para floats
            ■ %c - para chars
            ■ etc...
            ■ %@ - para objectos!! --> ObjC

 NSString *aString = @”Johnny”;
 NSString *log = [NSString stringWithFormat: @”It’s ‘%@’”, aString];
 //log would have been set to: "It’s ‘Johnny’"


    NSLog(@”I am a %@, I have %d items”, [array className], [array count]);
//Would print: "I am a NSArray, I have 5 items"
ObjC: apontadores nulos - nil
 ● Apontadores em ObjC podem ser nulos:

  int *numberPtr = nil;

 ● Testando um apontador nulo, explicitamente:

  if (numberPtr == nil) {return;}

 ● Testando um apontador nulo, implicitamente:

  if (!numberPtr) {return;}

 ● Podem ser usados em atribuições ou argumentos:
  numberPtr = nil;
  [myCalculator setValue: nil];

 ● Pode-se enviar mensagens para nil (são ignoradas...):
  myObject = nil;
  [myObject doSomething];
ObjC:
Identidade versus Igualdade entre Objectos

 ● Identidade
       ○ Teste da igualdade dos respectivos apontadores
       ○ "É o mesmo Objecto?"
 if (object1 == object2) {NSLog(@"Same exact object instance");}


 ● Igualdade
       ○ Teste da igualdade dos atributos (i.e. variáveis membras de cada objecto)
       ○ "Os Objectos têm o mesmo conteudo?"
 if ([object1 isEqual: object2]) {
    NSLog(@"Logically equivalent,
         but may be different object instances");
 }
ObjC: reponsabilidade pela vida de Objectos
#import <Foundation/Foundation.h>

@interface Veiculo : NSObject {

    // instance variables
    NSString *marca; //Veiculo class “owns” the NSString object 'marca'
    int velMax;
    //...
}

// method declarations
- (void)init;
- (NSString *)marca;
- (void)setMarca:(NSString *)novaMarca;
- (int)velMax;
- (void)setVelMax:(int)vel;
//...
@end
ObjC: reponsabilidade pela vida de Objectos
      #import "Veiculo.h"

      @implementation Veiculo

      -(id)init {
         // allow superclass to initialize its state first
         if (self = [super init]) {
            marca = @"não definida"; //this is a NSString
            velMax = 120;
            velActual = 0;
            numRodas = 4;
            numLugares = 4;
         }
         return self;
      }

      //other method implementations...

      @end
ObjC: reponsabilidade pela vida de Objectos
#import "Veiculo.h"                         Setter para um objecto criado pelo
                                                      nosso objecto
@implementation Veiculo                              Solução 1 (errada)

- (NSString *)marca { return marca;}

- (void)setMarca:(NSString *)novaMarca {
   marca = novaMarca; //!!! memory leak!!
}
@end



           ● Se marca apontasse para uma NSString já
             existente (e.g. alocada no construtor init da
             classe Veiculo) essa zona de memória ficaria
             "em fuga"...
ObjC: reponsabilidade pela vida de Objectos
#import "Veiculo.h"                                   Setter para um objecto criado pelo
                                                                nosso objecto
@implementation Veiculo                                     Solução 2 (ainda errada)

- (NSString *)marca { return marca;}

- (void)setMarca:(NSString *)novaMarca {
   [marca release]; //what if marca == novaMarca?!?
   marca = novaMarca;
}
@end

  ● Se por acaso novaMarca apontasse para a mesma NSString que marca
    aponta (pode acontecer!!), ao fazer release do apontador marca correria-se o
    risco de o retain counter cair para zero, e a NSString ser destruida!!

        ○ perder-se-ia a string que se pretendia usar para passar para o nosso
          objecto!!
ObjC: reponsabilidade pela vida de Objectos
#import "Veiculo.h"
                                                        Setter para um objecto criado pelo
@implementation Veiculo                                           nosso objecto
                                                             Solução 3a (CORRECTA!)
- (NSString *)marca { return marca;}

- (void)setMarca:(NSString *)novaMarca {
   if (marca != novaMarca)
   {
      [marca release];
      marca = [novaMarca retain];
      // marca’s retain count has been bumped up by 1
   }
}
@end                     ● Antes de tudo verifica-se se por acaso não estamos a receber um
                           apontador para um objecto NSString para o qual já estamos a
                           apontar
                              ○ Caso não seja, liberta-se o objecto anterior e aponta-se para o
                                que é passado como argumento
ObjC: reponsabilidade pela vida de Objectos
#import "Veiculo.h"
                                                       Setter para um objecto criado pelo
@implementation Veiculo
                                                                 nosso objecto
                                                            Solução 3b (CORRECTA!)
- (NSString *)marca { return marca;}

- (void)setMarca:(NSString *)novaMarca {
   if (marca != novaMarca)
   {
      [marca release];
      marca = [novaMarca copy];
      // marca’s retain count has been bumped up by 1
   }
}
@end              ● Neste caso não copiamos apenas o apontador...
                       ○ É criada uma cópia do objecto!!
                            ■ Evita que alterações na string por alguém que partilhe
                               apontadores para a "nossa" NSString marca
                                  ■ Na realidade, como o objecto NSString é imutável,
                                    esse problema não se coloca...
ObjC: reponsabilidade pela vida de Objectos
 ● Se alocamos... temos de "desalocar"!!
    ○ Caso contrário provocamos uma "fuga de memória" (memory leak)

        #import "Veiculo.h"

        @implementation Veiculo

        //...
        -(void) dealloc {
            //do any clean up that is needed...
            [marca release];

          //ask super to do its own clean up
          [super dealloc];
        }
        @end


                                          Oh Yeah! Embrace the power!! ;-)
ObjC: reponsabilidade pela vida de Objectos
   ● Retornar um objecto...
#import "Veiculo.h"

@implementation Veiculo

//...
-(NSString *) descricao {

  NSString *descricao;

  descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,
         com %d lugares...", [self numRodas], [self numLugares]);

  //remember: [NSString alloc] above bumps the retain count (i.e. +1)!

  return descricao;
}
@end



         ● ERRADO! fuga de memória!
                ○ [NSString alloc] incrementa o retain count...
                ○ Mas em lado algum é feito o correspondente release!
ObjC: reponsabilidade pela vida de Objectos
   ● Retornar um objecto...
#import "Veiculo.h"

@implementation Veiculo

//...
-(NSString *) descricao {

  NSString *descricao;

  descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,
         com %d lugares...", [self numRodas], [self numLugares]);
  //remember: [NSString alloc] above bumps the retain count (i.e. +1)!

  [descricao release]; //will this fix the memory leak? Yes... but we return bogus... :-

  return descricao;
}
@end

                               ● ERRADO! Retorna um apontador para um objecto inválido!
                                       ○ [NSString alloc] incrementa o retain count...
                                       ○ O release decrementa-o para zero
                                               ■ dealloc é chamado... objecto é destruído
                                               ■ Como resolver?!?!
ObjC: reponsabilidade pela vida de Objectos
   ● Retornar um objecto...
#import "Veiculo.h"

@implementation Veiculo

//...
-(NSString *) descricao {

  NSString *descricao;

  descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,
         com %d lugares...", [self numRodas], [self numLugares]);
  //remember: [NSString alloc] above bumps the retain count (i.e. +1)!

  [descricao autorelease]; //nice! ;-)

  return descricao;
}
@end

               ● CORRECTO!
                       ○ É feito o release ao objecto, mas não imediatamente...
                               ■ Dá-se assim tempo ao código que chamou o método de receber o apontador
                                 para um objecto que (ainda é válido!) e de logo a seguir fazer um retain
                       ○ Quando é então feito o "autorelease"??!
ObjC: reponsabilidade pela vida de Objectos
 ● O autorelease de Objectos

    ○ chamando -autorelease "marca" um objecto para ser enviado
      um release num momento futuro...

    ○ Cumpre-se com o requisito de "emparelhar" cada alloc com
      um release
        ■ Dando algum tempo ao objecto para sobreviver

    ○ Forma conveniente de gerir memória
        ■ muito útil em métodos que retornam objectos!
ObjC: reponsabilidade pela vida de Objectos
 ● O autorelease e nomes de métodos

    ○ Métodos cujos nomes comecem por alloc, copy ou
      new devolvem (i.e. retornam) objectos com retain count ==
      1
          ■ É necessário fazer release quando o objecto não for mais
            necessário!!
     NSMutableString *string = [[NSMutableString alloc] init];
     // We are responsible for calling -release or -autorelease
     [string autorelease];



    ○ Todos os outros métodos devolvem (i.e. retornam) objectos
      autoreleased (é apenas uma convenção!!)
   NSMutableString *string = [NSMutableString string];
   // The method name doesn’t indicate that we need to release it
   // So don’t- we’re cool!
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?

    ○ Objectos são adicionados a um "autorelease pool"

    ○ Este "autorelease pool" monitoriza objectos "marcados" para
      serem libertados (i.e. released)
       ■ Quando a própria "autorelease pool" é libertada, todos os
         objectos por ela monitorizados são também libertados (i.e.
         released)

    ○ Quando é a "autorelease pool" libertada??
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




         http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




         http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




         http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● Como funciona o autorelease?




        http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
ObjC: reponsabilidade pela vida de Objectos
 ● E não se corre o risco de "a qualquer momento" um objecto
   criado com autorelease com ficar inválido e não poder usar um
   apontador para ele??
     ○ Nesse caso, há que fazer retain!
  name = [NSMutableString string]; //autoreleased

  // We want to name to remain valid!
  [name retain];

  // ...

  // Eventually, we’ll release it (maybe in our -dealloc?)
  [name release];




 NOTA: autorelease não é Garbage Collection!!
Exercício: Classe Calculator e Fraction
      ● Implementar em ObjC uma classe Fraction:
               ○ armazena fracções (i.e. numerador / denominador)
               ○ imprime a fracção para a consola
               ○ realiza operações (+, -, *, /) entre fracções
#import <Foundation/Foundation.h>
#import "Fraction.h"
int main (int argc, const char * argv[]) {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *frac1 = [[Fraction alloc] init];
     Fraction *frac2 = [[Fraction alloc] init];
[frac1 setTo: 1 over: 3];
[frac1 print]; //print to console something like "1/3"
     [frac2 setTo: 5 over: 4];

     Fraction* result = [frac1 add: frac2]; //adds two fractions
     [result print];
[frac1 release];
     [frac2 release];
     [result release]
[pool drain];
return 0;
}
Fim

Cursos de Verão na Católica 2010
     http://porto.ucp.pt/cvc/

  Jorge C. S. Cardoso, Luís Gustavo Martins
jorgecardoso@ieee.org, lmartins@porto.ucp.pt



http://slideshare.net/jorgecardoso (tag: cvc2010)


  Código fonte: http://db.tt/AOFOfA2

Mais conteúdo relacionado

Mais procurados

Php5 e a orientação a objetos
Php5 e a orientação a objetosPhp5 e a orientação a objetos
Php5 e a orientação a objetosxbacon
 
Minicurso javascript
Minicurso javascriptMinicurso javascript
Minicurso javascriptLucas Aquiles
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricksTales Andrade
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e FuturesHelder da Rocha
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentesHelder da Rocha
 
Javascript para CSharpers 1 - Comparando
Javascript para CSharpers   1 - ComparandoJavascript para CSharpers   1 - Comparando
Javascript para CSharpers 1 - ComparandoWesley Lemos
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasHelder da Rocha
 
Javascript Avançado
Javascript AvançadoJavascript Avançado
Javascript AvançadoBruno Tavares
 
Iteraveis e geradores em Python
Iteraveis e geradores em PythonIteraveis e geradores em Python
Iteraveis e geradores em PythonLuciano Ramalho
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsHelder da Rocha
 
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricas
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricasCurso de OO com C# - Parte 05 - Coleções genéricas e não-genéricas
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricasLeonardo Melo Santos
 
Objective-C para quem está chegando agora
Objective-C para quem está chegando agoraObjective-C para quem está chegando agora
Objective-C para quem está chegando agoraEduardo Costa
 
Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicasHelder da Rocha
 
Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)Luciano Ramalho
 

Mais procurados (20)

Sobrecarga operadores
Sobrecarga operadoresSobrecarga operadores
Sobrecarga operadores
 
Php5 e a orientação a objetos
Php5 e a orientação a objetosPhp5 e a orientação a objetos
Php5 e a orientação a objetos
 
Minicurso javascript
Minicurso javascriptMinicurso javascript
Minicurso javascript
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricks
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e Futures
 
Javascript
JavascriptJavascript
Javascript
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentes
 
Programação Orientada por Objectos - Aula 5
Programação Orientada por Objectos - Aula 5Programação Orientada por Objectos - Aula 5
Programação Orientada por Objectos - Aula 5
 
Javascript para CSharpers 1 - Comparando
Javascript para CSharpers   1 - ComparandoJavascript para CSharpers   1 - Comparando
Javascript para CSharpers 1 - Comparando
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticas
 
Javascript Avançado
Javascript AvançadoJavascript Avançado
Javascript Avançado
 
Iteraveis e geradores em Python
Iteraveis e geradores em PythonIteraveis e geradores em Python
Iteraveis e geradores em Python
 
Palestra2009
Palestra2009Palestra2009
Palestra2009
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e Streams
 
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricas
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricasCurso de OO com C# - Parte 05 - Coleções genéricas e não-genéricas
Curso de OO com C# - Parte 05 - Coleções genéricas e não-genéricas
 
Floggy-JustJava-2008-09-10
Floggy-JustJava-2008-09-10Floggy-JustJava-2008-09-10
Floggy-JustJava-2008-09-10
 
Objective-C para quem está chegando agora
Objective-C para quem está chegando agoraObjective-C para quem está chegando agora
Objective-C para quem está chegando agora
 
Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicas
 
Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)Python para quem sabe Python (aula 2)
Python para quem sabe Python (aula 2)
 

Destaque

Introdução à programação em Android e iOS - Android
Introdução à programação em Android e iOS - AndroidIntrodução à programação em Android e iOS - Android
Introdução à programação em Android e iOS - AndroidLuís Gustavo Martins
 
Introdução à programação em Android e iOS - OOP Java
Introdução à programação em Android e iOS - OOP JavaIntrodução à programação em Android e iOS - OOP Java
Introdução à programação em Android e iOS - OOP JavaLuís Gustavo Martins
 
Introdução à programação em Android e iOS - Conceitos fundamentais de program...
Introdução à programação em Android e iOS - Conceitos fundamentais de program...Introdução à programação em Android e iOS - Conceitos fundamentais de program...
Introdução à programação em Android e iOS - Conceitos fundamentais de program...Luís Gustavo Martins
 
Technology Trends in Creativity and Business
Technology Trends in Creativity and BusinessTechnology Trends in Creativity and Business
Technology Trends in Creativity and BusinessLuís Gustavo Martins
 
Introdução à programação em Android e iOS - iOS
Introdução à programação em Android e iOS - iOSIntrodução à programação em Android e iOS - iOS
Introdução à programação em Android e iOS - iOSLuís Gustavo Martins
 

Destaque (6)

Introdução à programação em Android e iOS - Android
Introdução à programação em Android e iOS - AndroidIntrodução à programação em Android e iOS - Android
Introdução à programação em Android e iOS - Android
 
Introdução à programação em Android e iOS - OOP Java
Introdução à programação em Android e iOS - OOP JavaIntrodução à programação em Android e iOS - OOP Java
Introdução à programação em Android e iOS - OOP Java
 
Marsyas
MarsyasMarsyas
Marsyas
 
Introdução à programação em Android e iOS - Conceitos fundamentais de program...
Introdução à programação em Android e iOS - Conceitos fundamentais de program...Introdução à programação em Android e iOS - Conceitos fundamentais de program...
Introdução à programação em Android e iOS - Conceitos fundamentais de program...
 
Technology Trends in Creativity and Business
Technology Trends in Creativity and BusinessTechnology Trends in Creativity and Business
Technology Trends in Creativity and Business
 
Introdução à programação em Android e iOS - iOS
Introdução à programação em Android e iOS - iOSIntrodução à programação em Android e iOS - iOS
Introdução à programação em Android e iOS - iOS
 

Semelhante a ObjC Classe Veículo

Semelhante a ObjC Classe Veículo (20)

Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)Curso Desenvolvimento WEB com PHP - PHP (parte 1)
Curso Desenvolvimento WEB com PHP - PHP (parte 1)
 
OOP Java
OOP JavaOOP Java
OOP Java
 
Threads e Estruturas de dados
Threads e Estruturas de dadosThreads e Estruturas de dados
Threads e Estruturas de dados
 
Introdução a JavaScript
Introdução a JavaScriptIntrodução a JavaScript
Introdução a JavaScript
 
Desenvolvimento iOS
Desenvolvimento iOSDesenvolvimento iOS
Desenvolvimento iOS
 
TDC2013 Otimizando-C
TDC2013 Otimizando-CTDC2013 Otimizando-C
TDC2013 Otimizando-C
 
05 poo-ii
05   poo-ii05   poo-ii
05 poo-ii
 
Power mock
Power mockPower mock
Power mock
 
Objective-C
Objective-CObjective-C
Objective-C
 
Mock Objects
Mock ObjectsMock Objects
Mock Objects
 
RMI em Java
RMI em JavaRMI em Java
RMI em Java
 
Como criar classes e objetos
Como criar classes e objetosComo criar classes e objetos
Como criar classes e objetos
 
Como criar classes e objetos
Como criar classes e objetosComo criar classes e objetos
Como criar classes e objetos
 
Conexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das GaláxiasConexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das Galáxias
 
Curso de Groovy
Curso de GroovyCurso de Groovy
Curso de Groovy
 
tmn - Introdução ao JavaScript
tmn - Introdução ao JavaScripttmn - Introdução ao JavaScript
tmn - Introdução ao JavaScript
 
Minicurso groovy grails
Minicurso groovy grailsMinicurso groovy grails
Minicurso groovy grails
 
Groovy na plataforma Java
Groovy na plataforma JavaGroovy na plataforma Java
Groovy na plataforma Java
 
Mágica com qt’s meta object system
Mágica com qt’s meta object systemMágica com qt’s meta object system
Mágica com qt’s meta object system
 
LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09
 

Mais de Luís Gustavo Martins

Creativity and Design Thinking - 2024.pdf
Creativity and Design Thinking  - 2024.pdfCreativity and Design Thinking  - 2024.pdf
Creativity and Design Thinking - 2024.pdfLuís Gustavo Martins
 
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...Luís Gustavo Martins
 
ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...
 ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI... ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...
ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...Luís Gustavo Martins
 
Smart research? A retórica da Excelência.
Smart research? A retórica da Excelência.Smart research? A retórica da Excelência.
Smart research? A retórica da Excelência.Luís Gustavo Martins
 
Artificial intelligence and Creativity
Artificial intelligence and CreativityArtificial intelligence and Creativity
Artificial intelligence and CreativityLuís Gustavo Martins
 
The impact of Cultural Context on the Perception of Sound and Musical Languag...
The impact of Cultural Context on the Perception of Sound and Musical Languag...The impact of Cultural Context on the Perception of Sound and Musical Languag...
The impact of Cultural Context on the Perception of Sound and Musical Languag...Luís Gustavo Martins
 
Research methodology - What is a PhD?
Research methodology - What is a PhD?Research methodology - What is a PhD?
Research methodology - What is a PhD?Luís Gustavo Martins
 
A Computational Framework for Sound Segregation in Music Signals using Marsyas
A Computational Framework for Sound Segregation in Music Signals using MarsyasA Computational Framework for Sound Segregation in Music Signals using Marsyas
A Computational Framework for Sound Segregation in Music Signals using MarsyasLuís Gustavo Martins
 

Mais de Luís Gustavo Martins (11)

Creativity and Design Thinking - 2024.pdf
Creativity and Design Thinking  - 2024.pdfCreativity and Design Thinking  - 2024.pdf
Creativity and Design Thinking - 2024.pdf
 
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...
Inteligência Artificial - do hype, ao mito, passando pelas oportunidades e ri...
 
ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...
 ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI... ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...
ANDROIDS, REPLICANTS AND BLADE RUNNERS - ARE WE ALL DEEP DREAMING OF ELECTRI...
 
Smart research? A retórica da Excelência.
Smart research? A retórica da Excelência.Smart research? A retórica da Excelência.
Smart research? A retórica da Excelência.
 
Artificial intelligence and Creativity
Artificial intelligence and CreativityArtificial intelligence and Creativity
Artificial intelligence and Creativity
 
Creativity and Design Thinking
Creativity and Design ThinkingCreativity and Design Thinking
Creativity and Design Thinking
 
The impact of Cultural Context on the Perception of Sound and Musical Languag...
The impact of Cultural Context on the Perception of Sound and Musical Languag...The impact of Cultural Context on the Perception of Sound and Musical Languag...
The impact of Cultural Context on the Perception of Sound and Musical Languag...
 
Speaker Segmentation (2006)
Speaker Segmentation (2006)Speaker Segmentation (2006)
Speaker Segmentation (2006)
 
Research methodology - What is a PhD?
Research methodology - What is a PhD?Research methodology - What is a PhD?
Research methodology - What is a PhD?
 
Introduction to pattern recognition
Introduction to pattern recognitionIntroduction to pattern recognition
Introduction to pattern recognition
 
A Computational Framework for Sound Segregation in Music Signals using Marsyas
A Computational Framework for Sound Segregation in Music Signals using MarsyasA Computational Framework for Sound Segregation in Music Signals using Marsyas
A Computational Framework for Sound Segregation in Music Signals using Marsyas
 

ObjC Classe Veículo

  • 1. Programação Orientada a Objectos (OOP) - Parte 2: ObjC Cursos de Verão na Católica 2010 Jorge C. S. Cardoso, Luís Gustavo Martins jorgecardoso@ieee.org, lmartins@porto.ucp.pt
  • 2. Classe Veículo em ObjC Divisão do código em duas partes: 1. Interface ■ declarada num ficheiro Veiculo.h 2. Implementação ■ definida num ficheiro Veiculo.m http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 3. Classe Veículo em ObjC #import <Foundation/Foundation.h> Interface - Veiculo.h @interface Veiculo : NSObject { // instance variables int velMax; int velActual; int numRodas; int numLugares; } //setters and getters O ObjC "obriga" ao uso de getters e setters - (void) setVelMax: (int)vel; - (int) velMax; - (void) setVelActual: (int)vel; --> Encapsulamento! - (int) velActual; - (void) setNumRodas: (int)numRodas; - (int) numRodas; - (void) setNumLugares: (int)numLugares; - (int) numLugares; // other method declarations - (void) arrancar; - (void) travar; - (void) acelerar; - (void) buzinar; - (BOOL) estaParado; - (void) mostrarEstado; @end
  • 4. Classe Veículo em ObjC Implementação - Veiculo.m #import "Veiculo.h" @implementation Veiculo //setter and getters -(int)velMax { return velMax; } -(void) setVelMax: (int)vel { velMax = vel; ● Implementar setters/getters } //... similar for other setter/getters ● Implementar métodos //other methods -(void) arrancar { Getters e setters podem ser //implementação do método arrancar... criados automaticamente... } - properties -(void) travar { - synthesize // ... } //... other methods... @end
  • 5. Classe Veículo em ObjC Uso de Properties e Synthesized Getters e Setters #import <Foundation/Foundation.h> #import <Foundation/Foundation.h> @interface Veiculo : NSObject { // instance variables @interface Veiculo : NSObject { int velMax; // instance variables int velActual; int velMax; int numRodas; int velActual; int numLugares; int numRodas; } int numLugares; //setters and getters } - (void) setVelMax: (int)vel; //properties - (int) velMax; @property velMax; - (void) setVelActual: (int)vel; @property velActual; - (int) velActual; @property numRodas, numLugares; - (void) setNumRodas: (int)numRodas; - (int) numRodas; // other method declarations - (void) setNumLugares: (int)numLugares; - (void) arrancar; - (int) numLugares; - (void) travar; // other method declarations - (void) acelerar; - (void) arrancar; - (void) buzinar; - (void) travar; - (BOOL) estaParado; - (void) acelerar; - (void) mostrarEstado; - (void) buzinar; @end - (BOOL) estaParado; - (void) mostrarEstado; @end
  • 6. Classe Veículo em ObjC Uso de Properties e Synthesized Getters e Setters #import "Veiculo.h" #import "Veiculo.h" @implementation Veiculo @implementation Veiculo //setter and getters //synthesized setter and getters -(int)velMax { @synthesize velMax; return velMax; @synthesize velActual: } @synthesize numRodas; -(void) setVelMax: (int)vel { @synthesize numLugares; velMax = vel; } //other methods //... similar for other setter/getters -(void) arrancar { //implementação do método arrancar... //other methods } -(void) arrancar { //implementação do método arrancar... -(void) travar { } // ... } -(void) travar { // ... //... other methods... } @end //... other methods... @end
  • 7. Classe Veículo em ObjC Uso de Properties e Synthesized Getters e Setters ● É possível alterar o comportamento do setter sintetizado para uma variável membra, usando modificadores Num setter do tipo: -(void) setVar: (SomeClass *)value Se o sintetizarmos com os seguintes modificadores, teremos no corpo do setter (sintetizado) as seguintes atribuições: @property (assign) var var = value; //simple assignation @property (retain) var var = [value retain]; //assignation with reference counter increment @property (copy) var var = [value copy]; //object is copied (must conform to the NSCopying protocol...)
  • 8. Herança em ObjC ● O ObjC suporta herança simples ○ ou seja, uma classe apenas pode herdar de uma classe pai ■ Tal como o Java (outras linguagens, como o C++, suportam herança múltipla) ○ Em vez de herança multipla, o ObjC suposta o uso de "categories" e "protocols" (semelhantes às "interfaces" do Java) ■ http://developer.apple. com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocCategories.html ■ http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocProtocols. html#//apple_ref/doc/uid/TP30001163-CH15-SW1 http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 9. ObjC: Métodos de Classe e de Instância ● Instâncias respondem a métodos de instância: - (id) init; - (void) setVelMax: (int) vel; - (int) velMax; - (void) travar; ... ● Classes respondem a métodos de classe: + (id) alloc; + (id) Veiculo; + (Veiculo *) sharedVeiculo; ...
  • 10. ObjC: Mensagens para Objectos ● Em ObjC, em vez de se "chamar" métodos de objectos (como em Java ou C++), enviam-se "mensagens" ○ Sintaxe: [receiver message] [receiver message:argument] [receiver message:arg1 andArg:arg2] ● Exemplos: Veiculo *meuVeiculo; //assume this exists... [meuVeiculo trava]; [meuVeiculo setVelMax:300] //you wish!! ;-) [meuVeiculo vira:90 andPiscaPisca:YES]; int speed = [meuVeiculo velActual];
  • 11. ObjC: Mensagens para Objectos ● O "Dot-Syntax" ○ O ObjC 2.0 introduziu uma outra forma de se aceder a variáveis membras de um objecto Veiculo *meuVeiculo; //assume this exists... int speed1 = [meuVeiculo velActual]; //message int speed2 = meuVeiculo.velActual; //dot syntax [meuVeiculo setVelActual: 120]; //message meuVeiculo.velActual = 60; //dot syntax ○ O dot-syntax faz uso dos setters e getters!! ■ Não quebra o ENCAPSULAMENTO!!
  • 12. ObjC: Mensagens para Objectos ● O "Dot-Syntax" - Um problema frequente... ○ O que é que acontece quando o seguinte código executa? @implementation Person - (void)setAge:(int)newAge { //setter self.age = newAge; //age é uma variável membra } @end ○ É equivalente a: @implementation Person - (void)setAge:(int)newAge { //setter [self setAge:newAge]; // Infinite loop! } @end
  • 13. ObjC: self e super ● self - mensagens para o próprio Objecto #import "Veiculo.h" @implementation Veiculo -(BOOL) isFamilyVehicle { return ([self numLugares] >= 4); } //other method implementations... ● super - mensagens para o "pai" do Objecto -(void) doSomething { //call superclass implementation first... [super doSomething]; //now do our own stuff... int foo = bar; //... }
  • 14. ObjC: tipos dinâmicos e estáticos ● Objectos com tipos dinâmicos ○ id anObject; ■ apenas id e não id* ■ a não ser que se saiba o que se está a fazer... ■ tipo genérico: pode ser usado para apontar para qualquer objecto ● Objectos com tipos estáticos ○ Veiculo *meuVeiculo; ● O ObjC implementa verificação de tipos em compile-time (e não em run-time) ● O ObjC usa sempre "dynamic binding"
  • 15. ObjC: ciclo de vida de objectos ● Criação de Objectos ○ Processo de dois passos: ■ alocar memória para o objecto: +alloc ■ inicializar o estado do objecto: -init ■ Construtor Veiculo *meuVeiculo = nil; #import "Veiculo.h" meuVeiculo = [[Veiculo alloc] init]; @implementation Veiculo -(id)init { // allow superclass to initialize its state first if (self = [super init]) { velMax = 120; velActual = 0; numRodas = 4; numLugares = 4; } return self; } @end
  • 16. ObjC: ciclo de vida de objectos ● Criação de Objectos - Métodos init (construtores) ○ Uma classe pode definir múltiplos métods init ■ -(id) init; ■ -(id) initWithVelMax:(int) vel; ■ -(id) initWithVelMax:(int) vel velActual:(int) vel; ■ ... ○ Métodos menos específicos chamam tipicamente métodos mais específicos usando valores por omissão: -(id) init {return [self initWithVelMax: 120];} -(id) initWithVelMax:(int) vel { return [self initWithVelMax:vel velActual:0]; }
  • 17. ObjC: ciclo de vida de objectos ● Destruição de Objectos ○ Depois de criado com com alloc (normalmente seguido de init), e no caso de não mais ser necessário, um objecto deve ser "limpo" da memória! ■ Para cada alloc deverá haver um dealloc ■ caso contrário criam-se "fugas de memória"!! ■ No entanto, dealloc nunca é chamado directamente! ■ com uma excepção (ver mais à frente...) ■ existe um mecanismo para "desalocar" sem chamar dealloc ... ■ REFERENCE COUNTING
  • 18. ObjC: ciclo de vida de objectos ● Destruição de Objectos ○ REFERENCE COUNTING ■ Todos os objectos implementam um "retain count" ■ Herdado de NSObject ■ enquanto o "retain count" > 0, objectivo é mantido em memória e válido ■ +alloc e -copy criam objectos com "retain count" == 1 ■ -retain incrementa o "retain count" ■ -release decrementa o "retain count" ■ Quando o "retain count" atinge o valor 0 o objecto é destruído! ■ -dealloc é chamado automaticamente ■ Ponto de não retorno!
  • 19. ObjC: ciclo de vida de objectos ● Destruição de Objectos - REFERENCE COUNTING http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 20. ObjC: ciclo de vida de objectos ● Destruição de Objectos Veiculo *meuVeiculo = nil; meuVeiculo = [[Veiculo alloc] init]; [meuVeiculo setVelMax:120]; [meuVeiculo arranca]; [meuVeículo setVelActual: 50]; //... [meuVeiculo para]; //no more need for this object... [meuVeiculo release]; //meuVeiculo will be destroyed in case its retain //count is zero (i.e. no one else is pointing to it) //And in that case, sending messages to it will CRASH! [meuVeiculo arranca];//CRASH!!
  • 21. ObjC: ciclo de vida de objectos ● Destruição de Objectos Veiculo *meuVeiculo = nil; meuVeiculo = [[Veiculo alloc] init]; [meuVeiculo setVelMax:120]; [meuVeiculo arranca]; [meuVeículo setVelActual: 50]; //... [meuVeiculo para]; //no more need for this object... [meuVeiculo release]; meuVeiculo = nil; //good programming practice! [meuVeiculo arranca];//No longer crashes!:-) No effect...
  • 22. ObjC: ciclo de vida de objectos ● Destruição de Objectos - Destrutor ○ Implementação do método -dealloc #import "Veiculo.h" @implementation Veiculo -dealloc { //this is an override of NSObject dealloc //do any cleanup that is necessary... //... //when done, ask super to also clean itself up [super dealloc]; //only time you call dealloc explicitly! } //other method implementations... @end
  • 23. ObjC: a classe NSString ● Suporte genérico para strings Unicode ○ Unicode é um sistema de codificação de caracteres que suporta todas as linguagens do mundo ● Consistentemente usada na API Cocoa e Cocoa Touch ○ em prejuízo das C-strings (i.e. char *) ○ sem dúvida uma das classes mais usadas em Cocoa ● Em ObjC, "constant strings" são definidas como: @“just as simple” ● E "constant strings" são na realidade instâncias de NSString NSString *aString = @”Hello World!”;
  • 24. ObjC: a classe NSString ● Formatação de Strings ○ Semelhante ao usado em Java e C++ (e.g. printf) ■ %d - para ints ■ %f - para floats ■ %c - para chars ■ etc... ■ %@ - para objectos!! --> ObjC NSString *aString = @”Johnny”; NSString *log = [NSString stringWithFormat: @”It’s ‘%@’”, aString]; //log would have been set to: "It’s ‘Johnny’" NSLog(@”I am a %@, I have %d items”, [array className], [array count]); //Would print: "I am a NSArray, I have 5 items"
  • 25. ObjC: apontadores nulos - nil ● Apontadores em ObjC podem ser nulos: int *numberPtr = nil; ● Testando um apontador nulo, explicitamente: if (numberPtr == nil) {return;} ● Testando um apontador nulo, implicitamente: if (!numberPtr) {return;} ● Podem ser usados em atribuições ou argumentos: numberPtr = nil; [myCalculator setValue: nil]; ● Pode-se enviar mensagens para nil (são ignoradas...): myObject = nil; [myObject doSomething];
  • 26. ObjC: Identidade versus Igualdade entre Objectos ● Identidade ○ Teste da igualdade dos respectivos apontadores ○ "É o mesmo Objecto?" if (object1 == object2) {NSLog(@"Same exact object instance");} ● Igualdade ○ Teste da igualdade dos atributos (i.e. variáveis membras de cada objecto) ○ "Os Objectos têm o mesmo conteudo?" if ([object1 isEqual: object2]) { NSLog(@"Logically equivalent, but may be different object instances"); }
  • 27. ObjC: reponsabilidade pela vida de Objectos #import <Foundation/Foundation.h> @interface Veiculo : NSObject { // instance variables NSString *marca; //Veiculo class “owns” the NSString object 'marca' int velMax; //... } // method declarations - (void)init; - (NSString *)marca; - (void)setMarca:(NSString *)novaMarca; - (int)velMax; - (void)setVelMax:(int)vel; //... @end
  • 28. ObjC: reponsabilidade pela vida de Objectos #import "Veiculo.h" @implementation Veiculo -(id)init { // allow superclass to initialize its state first if (self = [super init]) { marca = @"não definida"; //this is a NSString velMax = 120; velActual = 0; numRodas = 4; numLugares = 4; } return self; } //other method implementations... @end
  • 29. ObjC: reponsabilidade pela vida de Objectos #import "Veiculo.h" Setter para um objecto criado pelo nosso objecto @implementation Veiculo Solução 1 (errada) - (NSString *)marca { return marca;} - (void)setMarca:(NSString *)novaMarca { marca = novaMarca; //!!! memory leak!! } @end ● Se marca apontasse para uma NSString já existente (e.g. alocada no construtor init da classe Veiculo) essa zona de memória ficaria "em fuga"...
  • 30. ObjC: reponsabilidade pela vida de Objectos #import "Veiculo.h" Setter para um objecto criado pelo nosso objecto @implementation Veiculo Solução 2 (ainda errada) - (NSString *)marca { return marca;} - (void)setMarca:(NSString *)novaMarca { [marca release]; //what if marca == novaMarca?!? marca = novaMarca; } @end ● Se por acaso novaMarca apontasse para a mesma NSString que marca aponta (pode acontecer!!), ao fazer release do apontador marca correria-se o risco de o retain counter cair para zero, e a NSString ser destruida!! ○ perder-se-ia a string que se pretendia usar para passar para o nosso objecto!!
  • 31. ObjC: reponsabilidade pela vida de Objectos #import "Veiculo.h" Setter para um objecto criado pelo @implementation Veiculo nosso objecto Solução 3a (CORRECTA!) - (NSString *)marca { return marca;} - (void)setMarca:(NSString *)novaMarca { if (marca != novaMarca) { [marca release]; marca = [novaMarca retain]; // marca’s retain count has been bumped up by 1 } } @end ● Antes de tudo verifica-se se por acaso não estamos a receber um apontador para um objecto NSString para o qual já estamos a apontar ○ Caso não seja, liberta-se o objecto anterior e aponta-se para o que é passado como argumento
  • 32. ObjC: reponsabilidade pela vida de Objectos #import "Veiculo.h" Setter para um objecto criado pelo @implementation Veiculo nosso objecto Solução 3b (CORRECTA!) - (NSString *)marca { return marca;} - (void)setMarca:(NSString *)novaMarca { if (marca != novaMarca) { [marca release]; marca = [novaMarca copy]; // marca’s retain count has been bumped up by 1 } } @end ● Neste caso não copiamos apenas o apontador... ○ É criada uma cópia do objecto!! ■ Evita que alterações na string por alguém que partilhe apontadores para a "nossa" NSString marca ■ Na realidade, como o objecto NSString é imutável, esse problema não se coloca...
  • 33. ObjC: reponsabilidade pela vida de Objectos ● Se alocamos... temos de "desalocar"!! ○ Caso contrário provocamos uma "fuga de memória" (memory leak) #import "Veiculo.h" @implementation Veiculo //... -(void) dealloc { //do any clean up that is needed... [marca release]; //ask super to do its own clean up [super dealloc]; } @end Oh Yeah! Embrace the power!! ;-)
  • 34. ObjC: reponsabilidade pela vida de Objectos ● Retornar um objecto... #import "Veiculo.h" @implementation Veiculo //... -(NSString *) descricao { NSString *descricao; descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas, com %d lugares...", [self numRodas], [self numLugares]); //remember: [NSString alloc] above bumps the retain count (i.e. +1)! return descricao; } @end ● ERRADO! fuga de memória! ○ [NSString alloc] incrementa o retain count... ○ Mas em lado algum é feito o correspondente release!
  • 35. ObjC: reponsabilidade pela vida de Objectos ● Retornar um objecto... #import "Veiculo.h" @implementation Veiculo //... -(NSString *) descricao { NSString *descricao; descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas, com %d lugares...", [self numRodas], [self numLugares]); //remember: [NSString alloc] above bumps the retain count (i.e. +1)! [descricao release]; //will this fix the memory leak? Yes... but we return bogus... :- return descricao; } @end ● ERRADO! Retorna um apontador para um objecto inválido! ○ [NSString alloc] incrementa o retain count... ○ O release decrementa-o para zero ■ dealloc é chamado... objecto é destruído ■ Como resolver?!?!
  • 36. ObjC: reponsabilidade pela vida de Objectos ● Retornar um objecto... #import "Veiculo.h" @implementation Veiculo //... -(NSString *) descricao { NSString *descricao; descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas, com %d lugares...", [self numRodas], [self numLugares]); //remember: [NSString alloc] above bumps the retain count (i.e. +1)! [descricao autorelease]; //nice! ;-) return descricao; } @end ● CORRECTO! ○ É feito o release ao objecto, mas não imediatamente... ■ Dá-se assim tempo ao código que chamou o método de receber o apontador para um objecto que (ainda é válido!) e de logo a seguir fazer um retain ○ Quando é então feito o "autorelease"??!
  • 37. ObjC: reponsabilidade pela vida de Objectos ● O autorelease de Objectos ○ chamando -autorelease "marca" um objecto para ser enviado um release num momento futuro... ○ Cumpre-se com o requisito de "emparelhar" cada alloc com um release ■ Dando algum tempo ao objecto para sobreviver ○ Forma conveniente de gerir memória ■ muito útil em métodos que retornam objectos!
  • 38. ObjC: reponsabilidade pela vida de Objectos ● O autorelease e nomes de métodos ○ Métodos cujos nomes comecem por alloc, copy ou new devolvem (i.e. retornam) objectos com retain count == 1 ■ É necessário fazer release quando o objecto não for mais necessário!! NSMutableString *string = [[NSMutableString alloc] init]; // We are responsible for calling -release or -autorelease [string autorelease]; ○ Todos os outros métodos devolvem (i.e. retornam) objectos autoreleased (é apenas uma convenção!!) NSMutableString *string = [NSMutableString string]; // The method name doesn’t indicate that we need to release it // So don’t- we’re cool!
  • 39. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? ○ Objectos são adicionados a um "autorelease pool" ○ Este "autorelease pool" monitoriza objectos "marcados" para serem libertados (i.e. released) ■ Quando a própria "autorelease pool" é libertada, todos os objectos por ela monitorizados são também libertados (i.e. released) ○ Quando é a "autorelease pool" libertada??
  • 40. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 41. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 42. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 43. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 44. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 45. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 46. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 47. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 48. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 49. ObjC: reponsabilidade pela vida de Objectos ● Como funciona o autorelease? http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter
  • 50. ObjC: reponsabilidade pela vida de Objectos ● E não se corre o risco de "a qualquer momento" um objecto criado com autorelease com ficar inválido e não poder usar um apontador para ele?? ○ Nesse caso, há que fazer retain! name = [NSMutableString string]; //autoreleased // We want to name to remain valid! [name retain]; // ... // Eventually, we’ll release it (maybe in our -dealloc?) [name release]; NOTA: autorelease não é Garbage Collection!!
  • 51. Exercício: Classe Calculator e Fraction ● Implementar em ObjC uma classe Fraction: ○ armazena fracções (i.e. numerador / denominador) ○ imprime a fracção para a consola ○ realiza operações (+, -, *, /) entre fracções #import <Foundation/Foundation.h> #import "Fraction.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *frac1 = [[Fraction alloc] init]; Fraction *frac2 = [[Fraction alloc] init]; [frac1 setTo: 1 over: 3]; [frac1 print]; //print to console something like "1/3" [frac2 setTo: 5 over: 4]; Fraction* result = [frac1 add: frac2]; //adds two fractions [result print]; [frac1 release]; [frac2 release]; [result release] [pool drain]; return 0; }
  • 52. Fim Cursos de Verão na Católica 2010 http://porto.ucp.pt/cvc/ Jorge C. S. Cardoso, Luís Gustavo Martins jorgecardoso@ieee.org, lmartins@porto.ucp.pt http://slideshare.net/jorgecardoso (tag: cvc2010) Código fonte: http://db.tt/AOFOfA2