Objektiv-C Succinkt Egenskaper

Nu när vi har undersökt vilka datatyper som är tillgängliga kan vi prata om att de faktiskt använder dem på ett produktivt sätt. Vi lärde oss att deklarera egenskaper i Hello, Objective-C, men det här kapitlet dyker djupare in i nyanser bakom offentliga egenskaper och instansvariabler. Först tar vi en snabb titt på grundsyntaxen för egenskaper och instansvariabler, och sedan diskuterar vi hur man använder beteend attributter för att modifiera accessor metoder.


Deklarera Egenskaper

Egenskaper kan deklareras i ett gränssnitt med hjälp av @fast egendom direktiv. Som en snabb recension, låt oss ta en titt på Person.h fil som vi skapade i kapitlet Hej, Objektiv-C:

#importera  @interface Person: NSObject @property (copy) NSString * namn; @slutet

Detta förklarar en egendom som heter namn av typ NSString. De (kopia) attributet berättar runtime vad som ska göras när någon försöker ställa in värdet av namn. I det här fallet skapas det en oberoende kopia av värdet istället för att peka på det befintliga objektet. Vi talar mer om detta i nästa kapitel, Memory Management.


Implementeringsegenskaper

I Hello, Objective-C, använde vi @synthesize direktivet för att automatiskt skapa getter och setter metoder. Kom ihåg att getter-metoden är helt enkelt namnet på egenskapen, och standard setter-metoden är Ange namn:

#import "Person.h" @implementation Person @synthesize name = _name; @slutet

Men det är också möjligt att manuellt skapa accessor metoder. Att göra detta manuellt bidrar till att förstå vad @fast egendom och @synthesize bakom kulisserna.

Inkluderat kodprov: ManualProperty

Lägg först en ny egendom till Person gränssnitt:

@property (copy) NSString * namn; @property unsigned int age;

Observera att vi lagrar ålder som en primitiv datatyp (inte en pekare till ett objekt), så det behöver inte en asterisk före egenskapens namn. Tillbaka in Person.m, definiera accessormetoderna explicit:

- (unsigned int) ålder return _age;  - (tomrum) setAge: (unsigned int) ålder _age = ålder; 

Det här är exakt vad @synthesize skulle ha gjort för oss, men nu har vi chansen att validera värden innan de tilldelas. Vi saknar emellertid en sak: _ålder instansvariabel. @synthesize skapade automatiskt en _namn ivar, tillåter oss att avstå från detta för namn fast egendom.


Instansvariabler

Instansvariabler, även kända som ivars, är variabler avsedda att användas inom klassen. De kan deklareras inuti lockiga hängslen efter antingen @gränssnitt eller @genomförande direktiven. Till exempel, i Person.h, ändra gränssnittsdeklarationen till följande:

@interface Person unsigned int _age; 

Detta definierar en instansvariabel som heter _ålder, så den här klassen bör nu kompilera framgångsrikt. Som standard är instansvariabler som deklareras i ett gränssnitt skyddad. Den motsvarande C # klassdefinitionen skulle vara något som:

klass Person skyddad uint _age; 

Objektiv-C-modifierare är desamma som i C #: privata variabler är endast tillgängliga för innehållsklassen, skyddade variabler är tillgängliga för alla underklasser, och offentliga variabler är tillgängliga för andra objekt. Du kan definiera omfattningen av instansvariabler med @privat, @skyddad, och @offentlig direktiv inom @gränssnitt, som visas i följande kod:

@interface Person: NSObject @private NSString * _ssn; @skyddad osignerad int @public NSString * jobb; 

Offentliga ivars är faktiskt lite utanför mål-C normer. En klass med offentliga variabler fungerar mer som en C-struktur än en klass; istället för den vanliga meddelandesyntaxen måste du använda -> pekare operatör. Till exempel:

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

Men i de flesta fall vill du gömma implementeringsdetaljer med hjälp av en @fast egendom deklaration istället för offentliga instansvariabler. Dessutom, eftersom exempelvariabler är tekniskt implementeringsdetaljer, gillar många programmerare att behålla Allt instansvariabler privata. Med detta i åtanke förklarade ivars i @genomförande är privata som standard. Så om du skulle flytta _ålder deklaration till Person.m istället för rubriken:

@implementation Person unsigned int _age; 

_ålder skulle scoped som a privat variabel. Tänk på detta när du arbetar med exempelvariabler i underklasser, eftersom de olika standardvärdena för gränssnitt mot implementeringsdeklarationen kan vara förvirrande för nykomlingar till Objective-C.

Anpassa Accessors

Men tillräckligt om exempelvariabler; låt oss komma tillbaka till fastigheter. Accessor metoder kan anpassas med flera attribut attribut attribut (t.ex.., (kopia)). Några av de viktigaste egenskaperna är:

  • getter = getterName - Anpassa namnet på getter accessor-metoden. Kom ihåg att standard är helt enkelt egenskapens namn.
  • setter = setterName - Anpassa namnet på setter accessor-metoden. Kom ihåg att standardvärdet är uppsättning följt av egendomens namn (t.ex.., Ange namn ).
  • readonly - Gör egenskapen skrivskyddad, vilket innebär att endast en getter kommer att syntetiseras. Egenskaper är som standard lässkriv. Detta kan inte användas med setter attribut.
  • nonatomic - Ange att accessormetoderna inte behöver vara trådlösa. Egenskaper är atomära som standard, vilket innebär att Objective-C kommer att använda ett lås / behåll (beskrivs i nästa kapitel) för att returnera komplett värde från en getter / setter. Observera dock att detta gör det inte garantera dataintegriteten över trådar - bara att getters och setters kommer att vara atomära. Om du inte befinner dig i en gängad miljö är icke-atomegenskaper mycket snabbare.

Ett vanligt fall för att anpassa getter namn är för Boolean namngivning konventioner. Många programmerare gillar att prepend är till booleska variabla namn. Detta är enkelt att genomföra via getter attribut:

@property (getter = isEmployed) BOOL anställd;

Internt kan klassen använda anställd variabel men andra objekt kan använda är anställd och setEmployed accessors att interagera med objektet:

Person * frank = [[Personallokering] init]; [frank setName: @ "Frank"]; [Frank setEmployed: YES]; om ([frank isEmployed]) NSLog (@ "Frank är anställd");  annars NSLog (@ "Frank är arbetslös"); 

Många av de andra egenskapsattributen avser minnehantering, som kommer att diskuteras i det kommande avsnittet. Det är också möjligt att tillämpa flera attribut på en enda egenskap genom att skilja dem med kommatecken:

@property (getter = isEmployed, readonly) BOOL anställd;

Punktsyntax

Förutom getter / setter metoder är det också möjligt att använda punktnotering för att få tillgång till deklarerade egenskaperna. För C # -utvecklare borde detta vara mycket mer välbekant än Objective-C: s kvadratfäste-meddelandesyntax:

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

Observera detta är bara en bekvämlighet-det översätts direkt till getter / setter-metoderna som beskrivits tidigare. Dot notation kan inte användas till exempel metoder.


Sammanfattning

Egenskaper är en integrerad aspekt av något objektorienterat programmeringsspråk. De är de data som metoderna fungerar på. De @fast egendom Direktivet är ett bekvämt sätt att konfigurera egenskapens beteende, men det gör inget som inte kan göras genom att manuellt skapa getter och setter metoder.

I nästa kapitel tar vi en detaljerad titt på hur egenskaper lagras i minnet, liksom några nya egenskaper för att styra detta beteende. Därefter dyker vi in ​​i metoder, som rundar ut objektivorienterade verktyg från Objective-C.

Denna lektion representerar ett kapitel från Objective-C Succinctly, en gratis eBook från laget vid Syncfusion.