Mål-C Succinkt Egenskaper

Nå som vi har utforsket hvilke datatyper som er tilgjengelige, kan vi snakke om å faktisk bruke dem på en produktiv måte. Vi lærte å deklarere egenskaper i Hello, Objective-C, men dette kapittelet dykker dypere inn i nyansene bak offentlige egenskaper og instansvariabler. Først tar vi en rask titt på grunnleggende syntaks av egenskaper og forekomstvariabler, og deretter diskuterer vi hvordan du bruker adferdsattributter for å endre tilgangsmetoder.


Deklarer Egenskaper

Egenskaper kan deklareres i et grensesnitt ved hjelp av @eiendom direktiv. Som en rask anmeldelse, la oss ta en titt på Person.h fil vi opprettet i Hei, Mål-C kapittel:

#importere  @interface Person: NSObject @property (copy) NSString * navn; @slutt

Dette erklærer en eiendom som kalles Navn av type NSString. De (kopiere) Attributt forteller kjøretiden hva du skal gjøre når noen prøver å sette verdien av Navn. I dette tilfellet oppretter det en uavhengig kopi av verdien i stedet for å peke på det eksisterende objektet. Vi snakker mer om dette i neste kapittel, Memory Management.


Implementere egenskaper

I Hei, Mål-C brukte vi @synthesize Direktivet for å automatisk lage getter og setter metoder. Husk at getter-metoden er bare navnet på eiendommen, og standard setter-metoden er setName:

#import "Person.h" @implementation Person @synthesize navn = _name; @slutt

Men det er også mulig å manuelt opprette tilgangsmetoder. Å gjøre dette manuelt bidrar til å forstå hva @eiendom og @synthesize gjør bak kulissene.

Inkludert kodeeksempel: ManualProperty

Først legger du til en ny eiendom i Person grensesnitt:

@property (copy) NSString * navn; @Property unsigned int alder;

Legg merke til at vi lagrer alder som en primitiv datatype (ikke en peker til en objekt), så det trenger ikke en stjerne før eiendomsnavnet. Tilbake i Person.m, definer tilgangsmetoder eksplisitt:

- (usignert int) alder return _age;  - (void) setAge: (usignert int) alder _age = alder; 

Dette er akkurat hva @synthesize ville ha gjort for oss, men nå har vi muligheten til å validere verdier før de blir tildelt. Vi mangler imidlertid en ting: _alder instansvariabel. @synthesize opprettet automatisk en _Navn ivar, slik at vi kan avgi dette for Navn eiendom.


Instansvariabler

Instansvariabler, også kjent som ivars, er variabler ment å bli brukt inne i klassen. De kan bli erklært inne i krøllete braces etter enten @interface eller @gjennomføring direktiver. For eksempel, i Person.h, endre grensesnittdeklarasjonen til følgende:

@interface Person usignert int _age; 

Dette definerer en instansvariabel som kalles _alder, så denne klassen skal nå kompilere med hell. Som standard er forekomstvariabler deklarert i et grensesnitt beskyttet. Den tilsvarende C # klassen definisjonen ville være noe som:

klasse Person beskyttet uint _age; 

Målvidde C-modifikatorer er de samme som i C #: Private variabler er bare tilgjengelige for den inneholdende klassen, beskyttede variabler er tilgjengelige for alle undergrupper, og offentlige variabler er tilgjengelige for andre objekter. Du kan definere omfanget av instansvariabler med @privat, @protected, og @offentlig direktiver inne i @interface, som vist i følgende kode:

@interface Person: NSObject @private NSString * _ssn; @ beskyttet usignert int _age; @ offentlig NSString * jobb; 

Offentlige ivars er faktisk litt utenfor mål-C normer. En klasse med offentlige variabler virker mer som en C-struktur enn en klasse; i stedet for den vanlige meldingssyntaxen, må du bruke -> pekeren operatør. For eksempel:

Person * Frank = [[Personallokering] init]; frank-> jobb = @ "Astronaut"; NSLog (@ "% @", frank-> jobb); // NOT: [frank jobb];

I de fleste tilfeller vil du imidlertid gjemme implementeringsdetaljer ved å bruke en @eiendom erklæring i stedet for offentlige instansvariabler. Videre, fordi forekommende variabler er teknisk implementeringsdetaljer, liker mange programmerere å beholde alle instansvariabler private. Med dette i tankene, erklærte ivars i @gjennomføring er som standard privat. Så, hvis du skulle flytte _alder erklæring til Person.m i stedet for overskriften:

@implementation Person unsigned int _age; 

_alder ville bli scoped som en privat variabel. Vær oppmerksom på dette når du arbeider med forekomstvariabler i underklasser, da de forskjellige standardene for grensesnittet mot implementeringsdeklarasjonen kan være forvirrende for nykommere til Objective-C.

Tilpasse Accessors

Men nok om forekomstvariabler; la oss komme tilbake til eiendommer. Tilgangsmetoder kan tilpasses ved hjelp av flere egenskapsdeklarasjonsattributter (f.eks., (kopiere)). Noen av de viktigste egenskapene er:

  • getter = getterName - Tilpass navnet på getter accessor-metoden. Husk at standard er rett og slett navnet på eiendommen.
  • setter = setterName - Tilpass navnet på setter accessor-metoden. Husk at standardinnstillingen er sett etterfulgt av eiendommens navn (f.eks., setName ).
  • skrivebeskyttet - Gjør eiendommen skrivebeskyttet, noe som betyr at bare en getter blir syntetisert. Egenskaper er som standard lese-skrive. Dette kan ikke brukes med Settere Egenskap.
  • nonatomic - Angi at tilgangsmetoder ikke trenger å være trådsikker. Egenskaper er atomisk som standard, noe som betyr at Objective-C vil bruke en lås / behold (beskrevet i neste kapittel) for å returnere fullstendig verdi fra en getter / setter. Vær imidlertid oppmerksom på at dette gjøres ikke garantere dataintegritet på tvers av tråder, bare at getters og setters vil være atomiske. Hvis du ikke er i et gjenget miljø, er ikke-atomiske egenskaper mye raskere.

Et vanlig brukstilfelle for å tilpasse getter-navn er for boolske navngivningskonvensjoner. Mange programmerere liker å prepend er til boolske variable navn. Dette er enkelt å implementere via getter Egenskap:

@property (getter = isEmployed) BOOL ansatt;

Internt kan klassen bruke ansatt variabel, men andre objekter kan bruke isEmployed og setEmployed accessors å samhandle med objektet:

Person * Frank = [[Personallokering] init]; [frank setName: @ "Frank"]; [Frank setEmployed: YES]; hvis ([frank isEmployed]) NSLog (@ "Frank er ansatt");  ellers NSLog (@ "Frank er arbeidsledig"); 

Mange av de andre egenskapsattributtene vedrører minnehåndtering, som vil bli diskutert i den kommende delen. Det er også mulig å bruke flere attributter til en enkelt egenskap ved å skille dem med kommaer:

@property (getter = isEmployed, readonly) BOOL ansatt;

Punktsyntaks

I tillegg til getter / setter metoder, er det også mulig å bruke punktnotering for å få tilgang til deklarerte egenskaper. For C # -utviklere, bør dette være mye mer kjent enn Objective-Cs firkantede brakett-syntaks:

Person * Frank = [[Personallokering] init]; frank.name = @ "Frank"; // Samme som [frank setName: @ "Frank"]; NSLog (@ "% @", frank.name); // Samme som [frank navn];

Merk dette er bare en bekvemmelighet - den oversetter direkte til getter / setter-metodene som er beskrevet tidligere. Punktnotasjon kan ikke brukes for eksempel metoder.


Sammendrag

Egenskaper er et integrert aspekt av ethvert objektorientert programmeringsspråk. De er dataene som metodene fungerer på. De @eiendom Direktivet er en praktisk måte å konfigurere egenskapens oppførsel på, men det gjør ikke noe som ikke kan gjøres ved å manuelt lage getter og setter metoder.

I neste kapittel tar vi detaljert titt på hvordan egenskaper lagres i minnet, samt noen få nye egenskapsattributter for å kontrollere denne oppførselen. Etter det vil vi dykke inn i metoder som runder ut de objektivorienterte verktøyene til Objective-C.

Denne leksjonen representerer et kapittel fra Objective-C Succinctly, en gratis eBok fra teamet på Syncfusion.