Nu we hebben onderzocht welke gegevenstypen beschikbaar zijn, kunnen we praten over het feit dat we ze op een productieve manier gebruiken. We hebben geleerd eigenschappen in Hello, Objective-C te declareren, maar dit hoofdstuk gaat dieper in op de nuances achter openbare eigenschappen en instantievariabelen. Eerst zullen we de basissyntaxis van eigenschappen en instantievariabelen snel bekijken en vervolgens bespreken we hoe we gedragsattributen kunnen gebruiken om accessor-methoden te wijzigen.
Eigenschappen kunnen worden gedeclareerd in een interface met behulp van de @eigendom
richtlijn. Laten we als snel overzicht eens kijken naar de Person.h
bestand dat we hebben gemaakt in het hoofdstuk Hallo, Doelstelling-C:
#importeren@interface Persoon: NSObject @property (kopie) NSString * naam; @einde
Hiermee wordt een eigenschap met de naam naam
van type NSString
. De (kopiëren)
attribuut vertelt de runtime wat te doen wanneer iemand de waarde van probeert in te stellen naam
. In dit geval maakt het een onafhankelijke kopie van de waarde in plaats van naar het bestaande object te wijzen. We zullen hier meer over vertellen in het volgende hoofdstuk, Geheugenbeheer.
In Hello, Objective-C, gebruikten we de @synthetiseren
richtlijn om automatisch getter- en settermethoden te maken. Houd er rekening mee dat de methode getter eenvoudigweg de naam van de eigenschap is en dat de standaardsettermethode dit is setName
:
#import "Person.h" @implementation Persoon @synthesize name = _name; @einde
Maar het is ook mogelijk om de accessormethoden handmatig te maken. Als u dit handmatig doet, begrijpt u wat @eigendom
en @synthetiseren
doen achter de schermen.
Inclusief codevoorbeeld: ManualProperty
Voeg eerst een nieuwe eigenschap toe aan de Persoon
interface:
@property (kopie) NSString * naam; @property unsigned int age;
Merk op dat we opslaan leeftijd
als een primitief gegevenstype (geen wijzer naar een object), dus het heeft geen asterisk nodig voor de eigenschapnaam. Terug in Person.m
, definieer de accessormethoden expliciet:
- (unsigned int) age return _age; - (ongeldig) setAge: (unsigned int) age _age = age;
Dit is precies wat @synthetiseren
zou hebben gedaan voor ons, maar nu hebben we de kans om waarden te valideren voordat ze worden toegewezen. We missen echter één ding: het _leeftijd
instantievariabele. @synthetiseren
automatisch aangemaakt a _naam
ivar, waardoor we kunnen afzien van de naam
eigendom.
Exemplaarvariabelen, ook bekend als ivars, zijn variabelen die bedoeld zijn om in de klas te worden gebruikt. Ze kunnen worden gedeclareerd in accolades achter de beide @interface
of @implementatie
richtlijnen. Bijvoorbeeld in Person.h
, verander de interface-verklaring naar het volgende:
@interface Person unsigned int _age;
Dit definieert een instantievariabele genaamd _leeftijd
, dus deze klasse moet nu met succes compileren. Standaard zijn de in een interface gedeclareerde instantievariabelen beschermde. De equivalente definitie van de C # -klasse zou er ongeveer zo uitzien:
class Person protected uint _age;
Objectieven-C scope-modifiers zijn hetzelfde als in C #: privévariabelen zijn alleen toegankelijk voor de bevattende klasse, beschermde variabelen zijn toegankelijk voor alle subklassen en openbare variabelen zijn beschikbaar voor andere objecten. U kunt het bereik van instantievariabelen definiëren met de @privaat
, @protected
, en @openbaar
richtlijnen in @interface
, zoals aangetoond in de volgende code:
@interface Persoon: NSObject @private NSString * _ssn; @protected unsigned int _age; @public NSString * job;
Openbare ivars zijn eigenlijk een beetje buiten Objective-C-normen. Een klasse met openbare variabelen werkt meer als een Cstruct dan als een klasse; in plaats van de gebruikelijke berichtensyntaxis, moet u de. gebruiken ->
wijzer operator. Bijvoorbeeld:
Persoon * frank = [[Person alloc] init]; frank-> job = @ "Astronaut"; NSLog (@ "% @", frank-> job); // NIET: [open werk];
In de meeste gevallen wilt u echter implementatiegegevens verbergen met behulp van een @eigendom
verklaring in plaats van openbare instantievariabelen. Bovendien, omdat instantievariabelen technisch implementatiedetails zijn, houden veel programmeurs het graag bij allemaal instantievariabelen privé. Met dit in gedachten, verklaarden ivars in @implementatie
zijn standaard privé. Dus, als je de _leeftijd
verklaring aan Person.m
in plaats van de kop:
@implementation Persoon unsigned int _age;
_leeftijd
zou worden omschreven als een privaat variabel. Houd dit in gedachten bij het werken met instantievariabelen in subklassen, omdat de verschillende standaardwaarden voor interface versus implementatieverklaring verwarrend kunnen zijn voor nieuwkomers in Objective-C.
Maar genoeg over instantievariabelen; laten we teruggaan naar eigenschappen. Accessormethoden kunnen worden aangepast met behulp van verschillende eigenschappen voor eigenschapsverklaringen (bijv., (kopiëren)
). Enkele van de belangrijkste kenmerken zijn:
getter = getterName
- Pas de naam aan van de methode accessor getter. Vergeet niet dat de standaardinstelling simpelweg de naam van de eigenschap is.setter = setterName
- Pas de naam van de methode setter accessor aan. Vergeet niet dat de standaardinstelling is reeks
gevolgd door de naam van de eigenschap (bijv., setName
).alleen lezen
- Maak de eigenschap alleen-lezen, wat betekent dat alleen een getter wordt gesynthetiseerd. Standaard zijn eigenschappen read-write. Dit kan niet worden gebruikt met de setter
attribuut.nonatomic
- Geef aan dat de accessormethoden niet draadveilig hoeven te zijn. Eigenschappen zijn standaard atomair, wat betekent dat Objective-C een vergrendeling / behouden gebruikt (beschreven in het volgende hoofdstuk) om de compleet waarde van een getter / setter. Merk echter op dat dit wel het geval is niet gegevensintegriteit over threads garanderen - alleen dat getters en setters atomair zijn. Als u zich niet in een omgeving met threads bevindt, zijn niet-atomaire eigenschappen veel sneller.Een veelgebruikt voorbeeld voor het aanpassen van getternamen is voor Booleaanse naamconventies. Veel programmeurs willen graag voorafgaan is
naar Booleaanse variabelenamen. Dit is gemakkelijk te implementeren via de verkrijger
attribuut:
@property (getter = is geïmplementeerd) BOOL gebruikt;
Intern kan de klas de gebruiken in dienst
variabele, maar andere objecten kunnen de isEmployed
en setEmployed
toegangen om te communiceren met het object:
Persoon * frank = [[Person alloc] init]; [frank setName: @ "Frank"]; [frank setEmployed: YES]; if ([frank is Uitgevoerd]) NSLog (@ "Frank is in dienst"); else NSLog (@ "Frank is werkloos");
Veel van de andere eigenschapsattributen hebben betrekking op geheugenbeheer, dat in de komende sectie zal worden besproken. Het is ook mogelijk om meerdere kenmerken toe te passen op een enkele eigenschap door ze te scheiden met komma's:
@property (getter = is geïmplementeerd, readonly) BOOL gebruikt;
Naast getter / setter-methoden is het ook mogelijk om de puntnotatie te gebruiken voor toegang tot de opgegeven eigenschappen. Voor C # -ontwikkelaars zou dit veel bekender moeten zijn dan de syntaxis van de vierkante haaks berichtenserver van Objective-C:
Persoon * frank = [[Person alloc] init]; frank.name = @ "Frank"; // Hetzelfde als [frank setName: @ "Frank"]; NSLog (@ "% @", frank.name); // Hetzelfde als [open naam];
Let op dit is slechts een gemak - het vertaalt zich direct naar de eerder beschreven getter / setter-methoden. Puntnotatie kan niet worden gebruikt voor bijvoorbeeld methoden.
Eigenschappen vormen een integraal onderdeel van elke objectgeoriënteerde programmeertaal. Het zijn de gegevens waarop de methoden werken. De @eigendom
directive is een handige manier om het gedrag van een eigenschap te configureren, maar het doet niets dat niet kan worden gedaan door handmatig getter- en settermethoden te maken.
In het volgende hoofdstuk zullen we gedetailleerd bekijken hoe eigenschappen worden opgeslagen in het geheugen, evenals een paar nieuwe eigenschapsattributen om dit gedrag te beheersen. Daarna gaan we dieper in op methoden, die de belangrijkste objectgeoriënteerde tools van Objective-C completeren.
Deze les vertegenwoordigt een hoofdstuk uit Objective-C bondig, een gratis eBoek van het team van Syncfusion.