Klasser, metoder og arv

Lage nye klasser

  1. File -> New file...

Navnekonvensjon

  • CamelCase på klasse- og filnavn
  • snakeCase for instanser av klassen

Definere og benytte klasser

Eksempel: SpotifyTrack.h
@interface SpotifyTrack : NSObject
@property (nonatomic, strong) NSString *id;
@property (nonatomic, strong) NSString *artist;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSURL *thumbnailUrl;
@end

/* Det blir nå automagisk laget settere og gettere */
Eksempel: SpotifyTrack.m
#import "SpotifyTrack.h"

@implementation SpotifyTrack
@end
.h og .m-filer?
  • h.-filen definerer som regel instansvariablene og public metoder
  • m.-filen inneholder implementasjonen av metodene
Import: Interfacer må importeres før bruk. Dvs. at når du vil bruke en klasse må du huske å importere den med #import "Klasse.h". Dette gjelder også når du skal definere interfacet (.h) i implementasjonsfila (.m).

Instansiere klasser

SpotifyTrack *track = [[SpotifyTrack alloc] init];

Konstruktører?

Objective-C har ikke egne konstruktører, men det er en konvensjon at alle metoder som begynner på init benyttes til dette. Eksempler:
Ikke parametrisk "konstruktør"
[[SpotifyTrack alloc] init]
Parameterisert "konstruktør"
[[SpotifyTrack alloc] initWithId:@"123" andTitle:@"D-D-Dance"]

Instansvariabler

  • Alle instansvariabler deklarert i .h-filen er automatisk interne (@protected)
  • Kan overstyres ved hjelp av 'scope directives'
@interface MyObject : NSObject {
/* Instans variabelen er bare tilgjengelig inne i klassen som deklarerer den */
@private
NSString * ettObjekt;

/* Instans variabelen er tilgjengelig i klassen som
deklarer den og for klasser som arver av den klassen */
@protected
NSString * ettObjekt;

/* Instans variabelen er tilgjengelig for alle */
@public
NSString * ettObjekt;

/* Kun tilgjengelig for klasser som ligger i ett og samme image. */
@package
NSString * ettObjekt;
}

//Metoder og properties puttes inn her

@end

Properties

  • Properties er en effektiv måte og lage en get og set metode for instansvariabler (ivars)
  • I nyere Objective-C trenger man ikke definere ivars om man definerer properties, da de blir automatisk laget om det ikke finnes en matchende ivars til property navnet
@interface SpotifyTrack : NSObject
@property (nonatomic, strong) NSString *id;
@property (nonatomic, strong) NSString *artist;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSURL *thumbnailUrl;
@end

/* Det automagisk laget settere og gettere som kan brukes slik: */
SpotifyTrack *track = [[SpotifyTrack alloc] init];
track.artist = @"The Killers"; // kaller setter
NSLog(@"Artist: %@", track.artist); // kaller getter

Styre oppførslen til properties

Når man bruker @property for å generere en getter og setter kan man bestemme oppførsel ved hjelp av flere parametre

Tilgjengelighet
  • readonly lager kun en getter og ikke en setter
  • readwrite lager både getter og setter (default)
Bestemme oppførselen til en setter
  • strong bestemmer at klassen som lager propertien eier instasvariabelen, og styrer minnehåndtering
  • weak klassen som lager propertien eier ikke instansvariabelen, og styrer derfor ikke minnehåndteringen
  • copy lager en kopi av instansvariabelen når man bruker setteren som blir generert av @property
  • assign setter verdien direkte. Brukes blant annet ofte på primitiver
Trådsikkerhet
  • atomic Default, men bør brukes sjelden da den er tregere. Har tilleggsfunksjonalitet som gjør at man alltid returnerer ett helt objekt når flere tråder snakker med setter og getter
  • nonatomic er ikke trådsikker og man kan risikere å få hente instansvariabelen samtidig som noen skriver til den

Metoder

Definere klassemetoder (statiske metoder, + foran)

+ (id)alloc /* Allokerer en plass i minne til objektet */

Definere instansmetoder (- foran)

- (id)init /* Gjør initialiseringen som kreves av et objekt for å bli klart */
Ofte bruker man en kombinasjon av klasse og instansmetoder, som vist under. alloc kalles først som en klassemetode slik at man allokerer plass til et objekt. Deretter kalles instansmetoden init.
[[MyObject alloc] init]

Objective-C Message Passing

  • I Objective-C kaller man ikke metoder på objekter, men sender en beskjed
  • Navngir ikke selve metoden, men hver parameter
  • Skriver metoder mer som om man snakker til objektet
Definere metoder
// Med to parametere
- (id)initWithId:(NSString *)id andTitle:(NSString *)title;

// Setter med et parameter
- (void)setTitle:(NSString *)title;

// Getter
- (NSString *)title;
Java eksempel
SpotifyTrack track = new SpotifyTrack("id", "I'm awsome!");

person.setTitle("I'm awsome!");

String title = track.getTitle();
Objective-C ekvivalent
SpotifyTrack *track = [[SpotifyTrack alloc] initWithId:@"id" andTitle:@"I'm awsome!"];

[track setTitle:@"I'm awsome!"];

NSString *title = [track title];

Navnekonvensjon

Objective-C er rimelig verbost når det kommer til metodenavn. Navnene blir en del av metodesignaturen og må brukes når man kaller på metoden senere.

Metodesignatur (worst case?):
- (id)initWithBitmapDataPlanes:(unsigned char **)planes 
                    pixelsWide:(NSInteger)width 
                    pixelsHigh:(NSInteger)height 
                 bitsPerSample:(NSInteger)bps 
               samplesPerPixel:(NSInteger)spp 
                      hasAlpha:(BOOL)alpha
                      isPlanar:(BOOL)isPlanar 
                colorSpaceName:(NSString *)colorSpaceName
                  bitmapFormat:(NSBitmapFormat)bitmapFormat 
                   bytesPerRow:(NSInteger)rowBytes
                  bitsPerPixel:(NSInteger)pixelBits
Sende melding til metoden:
[[NSBitmapImageRep alloc]
                     initWithBitmapDataPlanes:NULL
                     pixelsWide:nsRectFrameRect.size.width 
                     pixelsHigh:nsRectFrameRect.size.height
                     bitsPerSample:8 
                     samplesPerPixel:3 
                     hasAlpha:NO 
                     isPlanar:NO 
                     colorSpaceName:@"NSCalibratedRGBColorSpace" 
                     bytesPerRow:0 
                     bitsPerPixel:0];

Kalle metoder på samme klasse

[self enInstansmetode];
[MinKlasse enKlasseMetode];

Kalle på metoder med dot syntax

En alternativ måte å kalle tilgangsmetoder (accessor methods, get, set):

NSString *artist = track.artist;
track.title = @"I'm awsome!";
track.artist.firstname = @"Superman";
NSString *artist = [track artist]; 
[track setTitle:@"I'm awsome!"];
[[track artist] setFirstname:@"Superman"];

Terminologi

Message expression
	[person setAge:25];
Message
	setAge:25
Selector
	setAge:

Arv

Arv defineres i interface med Subclass : Superclass syntaks.
// i SpotifyTrack.h. Får SpotifyTrack til å arve fra NSObject
@interface SpotifyTrack : NSObject
@end
  • Rotklassen i Objective-C kalles NSObject
  • Arv spesifiseres i headerfilen (.h)
  • super brukes for å sende meldinger til klassen man arver fra. Eks. [super enmetodepåsuperklassen]