Obiectiv-C derivă sintaxa obiect din Smalltalk. Toate sintaxa pentru non-orientate-obiect operațiuni (inclusiv variabile primitive, pre-procesare, expresii, funcții declarații și apeluri de funcții) sunt identice cu cele din C, în timp ce sintaxa pentru caracteristici orientate obiect este o punere în aplicare a Smalltalk-stil de mesagerie.

MessagesEdit

Modelul Objective-C al programării orientate pe obiecte se bazează pe transmiterea mesajelor către instanțe de obiecte. În Objective-C nu se apelează o metodă; se trimite un mesaj., Acest lucru este diferit de modelul de programare în stil Simula utilizat de C++. Diferența dintre aceste două concepte este în modul în care este executat codul la care se face referire prin metoda sau numele mesajului. Într-un limbaj în stil Simula, numele metodei este în majoritatea cazurilor legat de o secțiune de cod din clasa țintă de către compilator. În Smalltalk și Objective-C, ținta unui mesaj este rezolvată în timpul rulării, obiectul receptor interpretând mesajul., O metodă este identificată printr — un selector sau SEL-un identificator unic pentru fiecare nume de mesaj, adesea doar un șir nul — terminat reprezentând numele său-și rezolvat la un indicator de metodă C care îl implementează: un IMP. O consecință a acestui fapt este că sistemul de transmitere a mesajelor nu are verificare de tip. Obiectul către care este direcționat mesajul — receptorul — nu este garantat să răspundă la un mesaj și, dacă nu, ridică o excepție.,

Trimite mesaj metodă a obiectului indicat de pointer obj ar avea nevoie de următorul cod în C++:

obj->method(argument);

În Objective-C, acest lucru este scris, după cum urmează:

;

„metoda” call este traduse de compilator la objc_msgSend(id-ul auto, SEL op, …) familie de funcții de rulare. Implementări diferite se ocupe de adăugiri moderne, cum ar fi super. În familiile GNU această funcție se numește objc_msg_sendv, dar a fost depreciată în favoarea unui sistem modern de căutare sub objc_msg_lookup.,ambele stiluri de programare au punctele forte și punctele slabe. Programarea orientată pe obiecte în stilul Simula (c++) permite moștenirea multiplă și executarea mai rapidă prin utilizarea legării în timp de compilare ori de câte ori este posibil, dar nu acceptă legarea dinamică în mod implicit. De asemenea, forțează toate metodele să aibă o implementare corespunzătoare, cu excepția cazului în care sunt abstracte. Programarea în stil Smalltalk, așa cum este utilizată în Objective-C, permite mesajelor să meargă neimplementate, cu metoda rezolvată până la implementarea sa în timpul rulării., De exemplu, un mesaj poate fi trimis unei colecții de obiecte, la care doar unii vor fi așteptați să răspundă, fără teama de a produce erori de rulare. De asemenea, transmiterea mesajelor nu necesită definirea unui obiect la momentul compilării. O implementare este încă necesară pentru ca metoda să fie apelată în obiectul derivat. (Consultați secțiunea de tastare dinamică de mai jos pentru mai multe avantaje ale legării dinamice (târzii).)

interfețe și implementăriedit

Objective-C necesită ca interfața și implementarea unei clase să fie în blocuri de cod declarate separat., Prin convenție, dezvoltatorii plasează interfața într-un fișier antet și implementarea într-un fișier de cod. Fișierele antet, în mod normal sufixate .h, sunt similare cu fișierele antet C, în timp ce fișierele de implementare (metodă), în mod normal sufixate .m, poate fi foarte similar cu fișierele de cod C.

InterfaceEdit

Acest lucru este analog cu declarațiile de clasă utilizate în alte limbaje orientate pe obiecte, cum ar fi C++ sau Python.

interfața unei clase este de obicei definită într-un fișier antet. O convenție comună este de a numi fișierul antet după numele clasei, de exemplu, mingea.,h ar conține interfața pentru mingea de clasă.o declarație de interfață ia forma:

în cele de mai sus, semnele plus denotă metode de clasă sau metode care pot fi apelate pe clasa în sine (nu pe o instanță), iar semnele minus denotă metode de instanță, care pot fi apelate doar pe o anumită instanță a clasei. Metodele de clasă nu au, de asemenea, acces la variabilele de instanță.,

codul De mai sus este echivalentă cu următoarele C++ interfață:

Rețineți că instanceMethod2With2Parameters:param2_callName: demonstrează intercalarea de selector segmente cu argumentul expresii, pentru care nu există nici un echivalent direct în C/C++.

Return types poate fi orice tip C standard, un pointer către un obiect generic Objective-C, un pointer către un anumit tip de Obiect, cum ar fi NSArray*, NSImage * sau NSString*, sau un pointer către clasa căreia îi aparține metoda (instancetype). Tipul implicit de returnare este ID-ul generic de tip Objective-C.,

argumentele metodei încep cu un nume care etichetează argumentul care face parte din numele metodei, urmat de un punct urmat de tipul argumentului așteptat între paranteze și numele argumentului. Eticheta poate fi omisă.un derivat al definiției interfeței este categoria, care permite adăugarea de metode la clasele existente.

ImplementationEdit

interfața declară doar interfața de clasă și nu metodele în sine: codul real este scris în fișierul de implementare., Fișierele Implementation (method) au în mod normal extensia .m, care a însemnat inițial „messages”.

@implementation classname+ (return_type)classMethod { // implementation}- (return_type)instanceMethod { // implementation}@end

metodele sunt scrise folosind declarațiile lor de interfață.Compararea Objective-C și C:

- (int)method:(int)i { return ;}

int function(int i) { return square_root(i);}

sintaxa permite pseudo-numirea de argumente.reprezentările interne ale unei metode variază între diferite implementări ale Objective-C., Dacă myColor este clasei de Culoare, de exemplu metoda -changeColorToRed:verde:albastru: ar putea fi etichetate intern _i_Color_changeColorToRed_green_blue. I este de a se referi la o metodă de instanță, cu clasa și apoi numele metodei anexate și colons schimbat la subliniere. Deoarece ordinea parametrilor face parte din numele metodei, aceasta nu poate fi modificată pentru a se potrivi stilului sau expresiei de codare ca și în cazul parametrilor true named.cu toate acestea, numele interne ale funcției sunt rareori utilizate direct. În general, mesajele sunt convertite în apeluri funcționale definite în biblioteca de execuție Objective-C., Nu se știe neapărat la ora legăturii ce metodă va fi apelată, deoarece clasa receptorului (obiectul fiind trimis mesajul) nu trebuie să fie cunoscută până la runtime.

InstantiationEdit

odată ce o clasă Objective-C este scrisă, ea poate fi instantiated. Aceasta se face prin alocarea mai întâi a unei instanțe neinitializate a clasei (un obiect) și apoi prin inițializarea acesteia. Un obiect nu este pe deplin funcțional până când ambii pași nu au fost finalizați., Acești pași ar trebui să fie realizat cu o singură linie de cod, astfel încât nu există niciodată un alocate obiect care nu a suferit de inițializare (și pentru că nu este înțelept să păstreze rezultatul intermediar de -init poate reveni un alt obiect decât acela pe care e chemat).,

Instanțierea cu cele default, nu-parametrul de inițializare:

MyObject *foo = init];

Instanțierea cu un custom inițializare:

MyObject *foo = initWithString:myString];

în cazul În care nu personalizat de inițializare este de a fi efectuate, „noua” metodă poate fi adesea folosit în loc de alloc-init mesaje:

MyObject *foo = ;

de Asemenea, unele clase implementează clasa metoda de initializare., Ca +new, se combina +alloc și -init, dar, spre deosebire de +new, se vor întoarce un autoreleased exemplu. Unele clasă metoda de initializare parametri:

MyObject *foo = ;MyObject *bar = ;

alloc mesaj alocă memorie suficientă pentru a ține toate variabilele exemplu pentru un obiect, seturi toate variabilele de instanta la valori de zero, și se transformă în memorie într-o instanță a clasei; pe parcursul inițializarea memoriei este un exemplu de superclasa.,

mesajul init efectuează configurarea instanței la creare. Metoda init este de multe ori scris, după cum urmează:

- (id)init { self = ; if (self) { // perform initialization of object here } return self;}

În exemplul de mai sus, observați id tip de retur. Acest tip înseamnă „pointer to any object” în Objective-C (consultați secțiunea Dynamic typing).

modelul inițializatorului este utilizat pentru a asigura că obiectul este inițializat corect prin superclasa sa înainte ca metoda init să efectueze inițializarea acestuia., Efectuează următoarele acțiuni:

  1. self = trimite instanței superclass un mesaj init și atribuie rezultatul la self (pointer la obiectul curent).
  2. dacă (self)verifică dacă indicatorul obiect returnat este valid înainte de a efectua orice inițializare.
  3. întoarcere de sinereturnează valoarea de sine apelantului.

un pointer obiect nevalid are valoarea nil; declarații condiționale, cum ar fi „dacă” trata nil ca un pointer nul, astfel încât codul de inițializare nu va fi executat în cazul în care a revenit nil., Dacă există o eroare în inițializare, metoda init ar trebui să efectueze orice curățare necesară, inclusiv trimiterea unui mesaj „release” către self și return nil pentru a indica faptul că inițializarea a eșuat. Orice verificare pentru astfel de erori trebuie să fie efectuată numai după ce a numit inițializarea superclass pentru a se asigura că distrugerea obiectului se va face corect.

Dacă o clasă are mai mult de o metodă de inițializare, doar una dintre ele („și-a desemnat inițializare”) trebuie să urmeze acest model; alții ar trebui să apel desemnate inițializare în loc de superclasa inițializare.,

ProtocolsEdit

în alte limbaje de programare, acestea se numesc „interfețe”.obiectivul-C a fost extins la următorul pentru a introduce conceptul de moștenire multiplă de specificație, dar nu de implementare, prin introducerea protocoalelor. Acesta este un model realizabil fie ca o clasă de bază abstractă multiplă moștenită în c++, fie ca o” interfață ” (ca în Java și C#). Objective-C utilizează protocoale ad – hoc numite protocoale informale și protocoale impuse de compilator numite protocoale formale.,

un protocol informal este o listă de metode pe care o clasă poate opta să le implementeze. Este specificat în documentație, deoarece nu are prezență în limbă. Protocoalele informale sunt implementate ca o categorie (vezi mai jos) pe NSObject și includ adesea metode opționale, care, dacă sunt implementate, pot schimba comportamentul unei clase. De exemplu, o clasă de câmp text ar putea avea un delegat care implementează un protocol informal cu o metodă opțională pentru efectuarea completării automate a textului tastat de utilizator., Câmpul de text descoperă dacă delegatul implementează această metodă (prin reflecție) și, dacă da, apelează metoda delegatului pentru a susține funcția de completare automată.

un protocol formal este similar cu o interfață în Java, C# și Ada 2005. Este o listă de metode pe care orice clasă se poate declara să le implementeze. Versiunile Objective-C înainte de 2.0 cereau ca o clasă să implementeze toate metodele într-un protocol pe care se declară că îl adoptă; compilatorul va emite o eroare dacă clasa nu implementează toate metodele din protocoalele sale declarate. Obiectiv-C 2.,0 adăugat suport pentru marcarea anumitor metode într-un protocol opțional, iar compilatorul nu va impune punerea în aplicare a metodelor opționale.

o clasă trebuie declarată pentru a implementa acel protocol pentru a se spune că este conformă cu acesta. Acest lucru este detectabil în timpul rulării. Protocoalele formale nu pot oferi implementări; ele asigură pur și simplu apelanții că clasele care se conformează protocolului vor oferi implementări. În biblioteca NeXT/Apple, protocoalele sunt utilizate frecvent de sistemul de obiecte distribuite pentru a reprezenta abilitățile unui obiect care se execută pe un sistem la distanță.,

sintaxa

@protocol NSLocking- (void)lock;- (void)unlock;@end

denotă că există ideea abstractă de blocare. Afirmând în clasa definiție că protocolul este pus în aplicare,

@interface NSLock : NSObject <NSLocking>// ...@end

cazuri de NSLock susțin că vor oferi o implementare pentru cele doua instanță metode.

Dynamic typingEdit

Objective-C, ca Smalltalk, poate utiliza tastarea dinamică: un obiect poate fi trimis un mesaj care nu este specificat în interfața sa., Acest lucru poate permite o flexibilitate sporită, deoarece permite unui obiect să „captureze” un mesaj și să trimită mesajul unui alt obiect care poate răspunde la mesaj în mod corespunzător sau, de asemenea, să trimită mesajul unui alt obiect. Acest comportament este cunoscut sub numele de redirecționare a mesajelor sau delegare (vezi mai jos). Alternativ, un handler de eroare poate fi utilizat în cazul în care mesajul nu poate fi redirecționat. Dacă un obiect nu transmite un mesaj, nu răspunde la acesta sau nu gestionează o eroare, atunci sistemul va genera o excepție de rulare., Dacă mesajele sunt trimise la zero (pointer obiect nul), acestea vor fi ignorate în tăcere sau ridica o excepție generică, în funcție de opțiunile compilatorului.

informațiile statice de tastare pot fi, de asemenea, opțional adăugate la variabile. Aceste informații sunt apoi verificate la momentul compilării. În următoarele patru afirmații, sunt furnizate informații de tip din ce în ce mai specifice. Declarațiile sunt echivalente în timpul rulării, dar informațiile suplimentare permit compilatorului să avertizeze programatorul dacă argumentul trecut nu se potrivește cu tipul specificat.,

- (void)setMyValue:(id)foo;

în declarația de mai sus, foo poate fi de orice clasă.

- (void)setMyValue:(id<NSCopying>)foo;

În declarația de mai sus, foo poate fi un exemplu de orice clasa care corespunde NSCopying protocol.

- (void)setMyValue:(NSNumber *)foo;

în declarația de mai sus, foo trebuie să fie o instanță a clasei NSNumber.

- (void)setMyValue:(NSNumber<NSCopying> *)foo;

În declarația de mai sus, foo trebuie să fie un exemplu de NSNumber clasă, și trebuie să se conformeze NSCopying protocol.,

în Objective-C, toate obiectele sunt reprezentate ca indicatoare, iar inițializarea statică nu este permisă. Cel mai simplu obiect este tipul la care Id (objc_obj *) indică, care are doar un pointer isa care descrie clasa sa. Alte tipuri de C, cum ar fi valorile și structurile, sunt neschimbate, deoarece nu fac parte din sistemul obiect. Această decizie diferă de modelul obiectului C++, unde structurile și clasele sunt unite.

ForwardingEdit

Obiectiv-C permite trimiterea unui mesaj către un obiect care poate să nu răspundă., În loc să răspundă sau pur și simplu să renunțe la mesaj, un obiect poate redirecționa mesajul către un obiect care poate răspunde. Redirecționarea poate fi utilizată pentru a simplifica implementarea anumitor modele de proiectare, cum ar fi modelul observer sau modelul proxy.

runtime Objective-C specifică o pereche de metode în Object

un obiect care dorește să implementeze forwarding are nevoie doar de a suprascrie metoda forwarding cu o nouă metodă pentru a defini comportamentul forwarding. Metoda de acțiune performv:: nu trebuie să fie înlocuită, deoarece această metodă efectuează doar o acțiune bazată pe selector și argumente., Observa SEL tip, care este tipul de mesaje în Objective-C.

Notă: în OpenStep, Cacao, și GNUstep, utilizate în mod obișnuit cadre de Objective-C, nu se folosesc la clasa Object. – (Void)forwardInvocation: (NSInvocation *)metoda anInvocation a clasei NSObject este utilizată pentru a face redirecționarea.

Exempluedit

Iată un exemplu de program care demonstrează elementele de bază ale redirecționării.

expeditor.h expeditor.m destinatar.h

#import <objc/Object.h>// A simple Recipient object.@interface Recipient : Object- (id)hello;@end

destinatar.m

#import "Recipient.h"@implementation Recipient- (id)hello { printf("Recipient says hello!\n"); return self;}@end

principal.,când compilați folosind gcc, compilatorul raportează:

compilatorul raportează punctul făcut anterior, că expeditorul nu răspunde la mesajele de salut. În această situație, este sigur să ignorați avertismentul de când a fost implementată redirecționarea. Care rulează programul produce această ieșire:

$ ./a.outRecipient says hello!

CategoriesEdit

în Timpul proiectării de Objective-C, una dintre principalele preocupări a fost mentenabilitatea de mare cod baze., Experiența din lumea programării structurate a arătat că una dintre principalele modalități de îmbunătățire a codului a fost împărțirea acestuia în bucăți mai mici. Objective-C a împrumutat și a extins conceptul de categorii din implementările Smalltalk pentru a ajuta la acest proces.mai mult, metodele dintr-o categorie sunt adăugate la o clasă în timpul rulării. Astfel, categoriile permit programatorului să adauge metode la o clasă existentă – o clasă deschisă-fără a fi nevoie să recompileze acea clasă sau chiar să aibă acces la codul sursă., De exemplu, dacă un sistem nu conține un corector ortografic în implementarea șirului, acesta ar putea fi adăugat fără a modifica codul sursă șir.

metodele din categorii devin imposibil de distins de metodele dintr-o clasă atunci când programul este rulat. O categorie are acces deplin la toate variabilele de instanță din clasă, inclusiv variabilele private.

dacă o categorie declară o metodă cu aceeași semnătură metodă ca o metodă existentă într-o clasă, metoda categoriei este adoptată. Astfel, categoriile nu numai că pot adăuga metode la o clasă, ci și înlocuiesc metodele existente., Această caracteristică poate fi utilizată pentru a remedia erorile din alte clase prin rescrierea metodelor lor sau pentru a provoca o schimbare globală a comportamentului unei clase în cadrul unui program. Dacă două categorii au metode cu același nume, dar diferite semnături metodă, este nedefinit care Categorie metoda este adoptată.alte limbi au încercat să adauge această caracteristică într-o varietate de moduri. TOM a luat sistemul Objective-C un pas mai departe și a permis adăugarea de variabile, de asemenea,. Alte limbi au folosit în schimb soluții bazate pe prototipuri, cel mai notabil fiind Self.

C# și Visual Basic.,Limbajele NET implementează funcționalități similare superficial sub formă de metode de extensie, dar acestea nu au acces la variabilele private ale clasei. Ruby și alte câteva limbaje de programare dinamice se referă la tehnica ca „monkey patching”.

Logtalk implementează un concept de categorii (ca prima clasă de entități) care subsumează Objective-C categoriile de funcționalitate (Logtalk categorii pot fi, de asemenea, utilizat ca granulație fină unități de compoziție atunci când se definesc, de exemplu, noi clase sau prototipuri; în special, un Logtalk categorie poate fi practic importate de către orice număr de clase și prototipuri).,acest exemplu construiește o clasă întreagă, definind mai întâi o clasă de bază cu doar metode de accesare implementate și adăugând două categorii, aritmetică și afișare, care extind clasa de bază. În timp ce Categoriile pot accesa membrii de Date private ai clasei de bază, este adesea o bună practică accesarea acestor membri de date private prin metodele de acces, ceea ce ajută la menținerea categoriilor mai independente de clasa de bază. Implementarea unor astfel de accesori este o utilizare tipică a categoriilor. Alta este utilizarea categoriilor pentru a adăuga metode la clasa de bază., Cu toate acestea, nu este considerată o bună practică utilizarea categoriilor pentru subclasa superioară, cunoscută și sub denumirea de patch-uri de maimuțe. Protocoalele informale sunt implementate ca o categorie pe baza clasei NSObject. Prin convenție, fișierele care conțin categorii care extind clasele de bază vor lua numele BaseClass+ExtensionClass.h.

întreg.h

#import <objc/Object.h>@interface Integer : Object { int integer;}- (int)integer;- (id)integer:(int)_integer;@end

întreg.m întreg + aritmetică.h

#import "Integer.h"@interface Integer (Arithmetic)- (id) add: (Integer *) addend;- (id) sub: (Integer *) subtrahend;@end

întreg+aritmetică.m întreg + afișa.h

#import "Integer.h"@interface Integer (Display)- (id) showstars;- (id) showint;@end

întreg+afișare.m main.,m

NotesEdit

Compilare este realizat, de exemplu, prin:

gcc -x objective-c main.m Integer.m Integer+Arithmetic.m Integer+Display.m -lobjc

se poate experimenta prin plecarea din #import „Integer+Aritmetică.h ” și linii și omițând întreg + aritmetică.m în compilație. Programul va rula în continuare. Aceasta înseamnă că este posibil să se amestece și să se potrivească categoriile adăugate, dacă este necesar; dacă o categorie nu trebuie să aibă o anumită abilitate, pur și simplu nu poate fi compilată.

PosingEdit

Obiectiv-C permite unei clase să înlocuiască în întregime o altă clasă într-un program. Se spune că clasa de înlocuire „reprezintă” clasa țintă.,

clasa care prezintă a fost declarată depreciată cu Mac OS X v10.5, și nu este disponibilă în timpul de rulare pe 64 de biți. Funcționalitate similară poate fi realizată prin utilizarea metodei swizzling în categorii, care swaps punerea în aplicare a unei metode cu altul care au aceeași semnătură.

pentru versiunile care acceptă în continuare posing, toate mesajele trimise clasei țintă sunt în schimb primite de clasa posing. Există mai multe restricții:

  • o clasă poate reprezenta doar una dintre superclasele sale directe sau indirecte.,
  • clasa care prezintă nu trebuie să definească nicio variabilă de instanță nouă care este absentă din clasa țintă (deși poate defini sau suprascrie metodele).
  • este posibil ca clasa țintă să nu fi primit niciun mesaj înainte de prezentare.prezentarea, în mod similar cu categoriile, permite augmentarea globală a claselor existente. Posing permite două caracteristici absente din categorii:
    • o clasă posing poate apela metode suprascrise prin super, încorporând astfel implementarea clasei țintă.
    • o clasă care prezintă poate înlocui metodele definite în categorii.,

    de exemplu,

    aceasta interceptează fiecare invocare a setMainMenu la NSApplication.

    #importEdit

    În limbajul C, #include pre-compilare directiva provoacă întotdeauna un fișier conținutul să fie introdus în sursa de la acel moment. Obiectiv-C are #import directiva, echivalente cu excepția faptului că fiecare fișier este inclus o singură dată pe compilatia unitate, nemaifiind nevoie pentru a include paznici.

    Linux gcc compilationEdit

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *