Acum, că am explorat ce tipuri de date sunt disponibile, putem vorbi despre utilizarea efectivă a acestora într-o manieră productivă. Am învățat cum să declare proprietățile în Hello, Objective-C, dar acest capitol scufundă mai adânc în nuanțele din spatele proprietăților publice și variabilelor de instanță. În primul rând, vom examina rapid sintaxa de bază a proprietăților și variabilelor de instanțe și vom discuta cum să folosim atribute de comportament pentru a modifica metodele accesorilor.
Proprietățile pot fi declarate într - o interfață utilizând @proprietate
directivă. Ca o revizuire rapidă, să aruncăm o privire la Person.h
fișierul pe care l-am creat în capitolul Hello, Obiectiv-C:
#import@interface Persoana: NSObject @property (copy) NSString * name; @Sfârșit
Aceasta declară o proprietate numită Nume
de tip NSString
. (copie)
atributul indică runtime-ului ce trebuie făcut când cineva încearcă să stabilească valoarea Nume
. În acest caz, se creează o copie independentă a valorii în loc să se indice către obiectul existent. Vom vorbi mai multe despre acest lucru în capitolul următor, Managementul memoriei.
În Hello, Obiectiv-C, am folosit @sintetiza
directivă pentru a crea automat metode getter și setter. Amintiți-vă că metoda getter este pur și simplu numele proprietății, iar metoda implicită de setare este Pune un nume
:
#import "Person.h" @implementation Persoană @synthesize name = _name; @Sfârșit
Dar, este posibil, de asemenea, să creați manual metodele accesorilor. Făcând acest lucru manual ajută să înțelegi ce @proprietate
și @sintetiza
se fac în spatele scenei.
Eșantion de cod inclus: ManualProperty
Mai întâi, adăugați o proprietate nouă la Persoană
interfaţă:
@property (copy) NSString * nume; @ vârstă nespecificată de serviciu;
Rețineți că stocăm vârstă
ca tip primitiv de date (nu un pointer la un obiect), deci nu are nevoie de un asterisc inainte de numele proprietatii. Înapoi în Person.m
, definesc explicit metodele accesorilor:
- (nesemnate int) vârstă return _age; - (void) setAge: (nesemnate int) vârstă _age = vârstă;
Asta e exact ce @sintetiza
ar fi făcut pentru noi, dar acum avem șansa de a valida valorile înainte ca acestea să fie atribuite. Cu toate acestea, ne lipsește un singur lucru: _vârstă
variabila de instanta. @sintetiza
a creat automat o _Nume
ivar, permițându-ne să renunțăm la acest lucru Nume
proprietate.
Variabilele de instanță, cunoscute și sub numele de ivars, sunt variabile destinate a fi utilizate în interiorul clasei. Acestea pot fi declarate în interiorul acoladelor după două @interface
sau @implementation
directive. De exemplu, în Person.h
, modificați declarația de interfață la următoarele:
@interface Persoana unsigned int _age;
Aceasta definește o variabilă de instanță numită _vârstă
, astfel încât această clasă ar trebui să se compileze acum cu succes. În mod implicit, variabilele de instanță declarate într-o interfață sunt protejat. Definiția echivalentă a clasei C # ar fi ceva de genul:
clasa Persoana protejat uint _age;
Modificatoarele de dimensiune obiectiv-C sunt aceleași ca în C #: variabilele private sunt accesibile numai pentru clasa care le conține, variabilele protejate sunt accesibile tuturor subclaselor și variabilele publice sunt disponibile altor obiecte. Puteți defini domeniul de aplicare al variabilelor instanței cu @privat
, @protejat
, și @public
directive în interiorul @interface
, după cum se arată în următorul cod:
@interface Persoana: NSObject @private NSString * _ssn; @protected unsigned int _age; Funcția publică NSString *;
Iarrele publice sunt de fapt un pic în afara normelor Obiectiv-C. O clasă cu variabile publice acționează mai mult ca o structură C decât o clasă; în loc de sintaxa de mesagerie obișnuită, trebuie să utilizați ->
pointer operator. De exemplu:
Persoana * frank = [[Person alloc] init]; frank-> job = @ "Astronaut"; NSLog (@ "% @", frank-> job); // NU: [serviciu franc];
Cu toate acestea, în majoritatea cazurilor, veți dori să ascundeți detaliile implementării utilizând o aplicație @proprietate
în loc de variabilele instanței publice. Mai mult, deoarece variabilele instanțelor sunt detalii de implementare tehnică, mulți programatori le place să le păstreze toate instanțe variabile private. Având în vedere acest lucru, au declarat ierbii @implementation
sunt private în mod implicit. Deci, dacă trebuia să mutați _vârstă
declarație către Person.m
în loc de antet:
@implementation Persoana unsigned int _age;
_vârstă
ar fi ca scop privat variabil. Țineți cont de acest lucru atunci când lucrați cu variabilele de instanță din subclase, deoarece diferitele valori prestabilite pentru interfață față de declarația de implementare pot fi confuze pentru noii veniți în Obiectiv-C.
Dar destul despre variabilele instanței; să ne întoarcem la proprietăți. Metodele accesorilor pot fi personalizate utilizând mai multe atribute ale declarației de proprietate (de ex., (copie)
). Unele dintre cele mai importante atribute sunt:
getter = getterName
- Personalizați numele metodei accessor getter. Amintiți-vă că implicit este pur și simplu numele proprietății.setter = setterName
- Personalizați numele metodei accesorilor setter. Amintiți-vă că implicit este a stabilit
urmată de numele proprietății (de ex., Pune un nume
).numai citire
- Faceți proprietatea numai pentru citire, adică doar un getter va fi sintetizat. Implicit, proprietățile sunt citite și scrise. Acest lucru nu poate fi utilizat cu prepelicar
atribut.nonatomic
- Indicați că metodele accesorilor nu trebuie să fie în siguranță. Proprietățile sunt implicit atomice, ceea ce înseamnă că obiectivul C va utiliza o blocare / reținere (descrisă în următorul capitol) pentru a returna complet valoare de la un getter / setter. Rețineți însă că acest lucru este posibil nu garantează integritatea datelor în fire - doar că getters și setters vor fi atomi. Dacă nu sunteți într-un mediu cu filet, proprietățile non-atomice sunt mult mai rapide.Un caz de utilizare obișnuit pentru personalizarea numelor getter este pentru convențiile de numire booleană. Mulți programatori preferă să predea este
la numele variabilelor Boolean. Acest lucru este ușor de implementat prin reproducător
atribut:
@property (getter = isEmployed) BOOL angajat;
Pe plan intern, clasa poate folosi angajat
variabile, dar alte obiecte pot folosi este angajat
și setEmployed
accesori pentru a interacționa cu obiectul:
Persoana * frank = [[Person alloc] init]; [frank setName: @ "Frank"]; [frank setEmployed: YES]; dacă [[franc este angajat]) NSLog (@ "Frank este angajat"); altfel NSLog (@ "Frank este șomer");
Multe dintre celelalte atribute ale proprietății se referă la gestionarea memoriei, care va fi discutată în secțiunea viitoare. De asemenea, este posibil să se aplice mai multe atribute unei singure proprietăți, separându-le cu virgule:
@property (getter = este angajat, readonly) BOOL angajat;
În plus față de metodele getter / setter, este posibilă utilizarea notației punctuale pentru a accesa proprietățile declarate. Pentru dezvoltatorii C #, aceasta ar trebui să fie mult mai familiarizată decât sintaxa de mesagerie a patratelor pentru obiectivul C:
Persoana * frank = [[Person alloc] init]; frank.name = @ "Frank"; // La fel ca [frank setName: @ "Frank"]; NSLog (@ "% @", frank.name); // La fel ca [numele sincer];
Rețineți că aceasta este o simplă comoditate - se traduce direct în metodele getter / setter descrise anterior. Notație notată nu poti de exemplu, metode.
Proprietățile reprezintă un aspect integral al oricărui limbaj de programare orientat pe obiecte. Acestea sunt datele la care funcționează metodele. @proprietate
direcția este o modalitate convenabilă de a configura comportamentul unei proprietăți, dar nu face nimic care nu poate fi făcut prin crearea manuală a metodelor getter și setter.
În capitolul următor, vom examina detaliat cum sunt stocate proprietățile în memorie, precum și câteva atribute noi de proprietate pentru controlul acestui comportament. După aceea, ne vom arunca cu capul în metode, care rotunjează instrumentele de bază ale obiectivului Obiectiv-C.
Această lecție reprezintă un capitol din Obiectiv-C Succinct, o carte electronică gratuită de la echipa de la Syncfusion.