Objective-C, får sin objektet syntaksen fra Smalltalk. Alle syntaks for ikke-objekt-orientert virksomhet (inkludert primitive variabler, pre-prosessering, uttrykk, funksjon erklæringer, og funksjonskall) er identiske med de av C, mens syntaks for objekt-orienterte har en implementering av Smalltalk-stil meldinger.
MessagesEdit
The Objective-C modell av objekt-orientert programmering er basert på melding pasning til objektet tilfeller. I Objective-C, et ikke kaller en metode; man sender en melding., Dette er i motsetning til Simula-stil programmering modell som brukes av C++. Forskjellen mellom disse to begrepene er i hvordan koden er referert til av metode eller melding navnet er utført. I en Simula-stil, språk, metode navn er i de fleste tilfeller er bundet til en del av koden i mål klasse av kompilatoren. I Smalltalk og Objective-C, målet om en melding er løst ved kjøring, med det mottatte objektet i seg selv å tolke budskapet., En metode er identifisert av en selector-eller SEL — en unik identifikator for hver melding med navn, ofte bare en NULL-avsluttet streng som representerer sitt navn — og løst til en C-metode pekeren for å implementere det: en IMP. En konsekvens av dette er at meldingen-passerer-systemet har ikke skrive sjekker. Objektet som meldingen er rettet — mottakeren er ikke garantert å svare på en melding, og hvis den ikke gjør det, det viser et unntak.,
Sender meldingen metode for å objektet peker til pekeren obj ville kreve følgende kode i C++:
obj->method(argument);
I Objective-C, dette er skrevet som følger:
;
«metode» kaller er oversatt av kompilatoren til objc_msgSend(id selv, SEL op …) familie på runtime-funksjoner. Ulike implementeringer håndtere moderne tilskuddene som super. I GNU familier denne funksjonen er oppkalt objc_msg_sendv, men det har blitt avskrevet i favør av en moderne oppslag systemet under objc_msg_lookup.,
Begge stiler av programmering har sine styrker og svakheter. Objekt-orientert programmering i Simula (C++) stil gjør at flere arv og raskere gjennomføring ved hjelp av compile-time bindende når det er mulig, men er det ikke støtte for dynamisk binding som standard. Det tvinger alle metoder for å få en tilsvarende implementering, med mindre de er abstrakte. Den Smalltalk-stil programmering som brukes i Objective-C, gjør at meldinger for å gå unimplemented, med den metoden som ble løst til gjennomføringen ved kjøring., For eksempel, en melding kan bli sendt til en samling av objekter, som bare noen som vil bli forventet å svare, uten frykt for å produsere runtime feil. Melding passerer også krever ikke at et objekt defineres på kompilere tid. En implementering er fortsatt nødvendig for metoden kalles i avledet objekt. (Se de dynamiske å skrive avsnittet nedenfor for mer fordeler av dynamiske (sen) bindende.)
Grensesnitt og implementationsEdit
Objective-C, krever at grensesnittet og gjennomføring av en klasse være i separat erklært kode blokker., Ved konvensjonen, utviklere sted grensesnittet i en header-filen og gjennomføringen i et koden fil. Header-filer, vanligvis etterfølges .h, er lik C header filer mens gjennomføringen (metode) – filer, vanligvis etterfølges .m, kan være svært lik C-kode-filer.
InterfaceEdit
Dette er analogt til klasse erklæringer som brukes i andre objekt-orientert språk som C++ eller Python.
grensesnittet av en klasse er vanligvis definert i en header-filen. En felles konvensjonen er å gi navn til header-filen etter navnet på klassen, f.eks. Ball.,h vil inneholde grensesnitt for klasse Ball.
Et grensesnitt erklæringen tar form:
I den ovenfor, pluss tegn betegne klasse metoder, eller metoder som kan kalles på klasse i seg selv (ikke på en forekomst), og minus tegn betegne eksempel metoder, som kan bli kalt på en bestemt instans av klassen. Klasse metoder også har ingen tilgang til eksempel variabler.,
koden ovenfor er omtrent tilsvarende de følgende C++ – grensesnitt:
Merk at instanceMethod2With2Parameters:param2_callName: viser den innfelte av selector segmenter med argumentet uttrykk, for der er det ingen direkte parallell i C/C++.
gå Tilbake typer kan være en hvilken som helst standard C-type, en peker til en generisk Objective-C, objekt, en peker til en bestemt type objekt som NSArray *, NSImage *, eller NSString *, eller en peker til den klassen som metode tilhører (instancetype). Standard returtypen er den generisk Objective-C type id.,
Metode argumenter begynner med et navn å merke argument som er en del av metoden navn, etterfulgt av et kolon etterfulgt av forventet argumentet type i parentes og argumentet navn. Etiketten kan være utelatt.
Et derivat av grensesnitt definisjon er den kategorien, som gjør det mulig å legge til metoder til eksisterende klasser.
ImplementationEdit
grensesnittet bare erklærer klasse grensesnitt og ikke metodene i seg selv: den faktiske koden er skrevet i gjennomføringen fil., Gjennomføring (metode) filer som normalt har den file extension .m
, som opprinnelig giv «meldinger».
@implementation classname+ (return_type)classMethod { // implementation}- (return_type)instanceMethod { // implementation}@end
Metodene som er skrevet ved hjelp av sine grensesnitt erklæringer.Å sammenligne Objective-C og C:
- (int)method:(int)i { return ;}
int function(int i) { return square_root(i);}
syntaksen gjør pseudo-navngiving av argumenter.
Interne representasjoner av en metode variere mellom ulike implementasjoner av Objective-C., Hvis myColor er av klassen Farge, for eksempel metode -changeColorToRed:grønn:blått: kan være internt merket _i_Color_changeColorToRed_green_blue. Jeg er for å se et eksempel metode, med klassen, og metoden navn vedlagte og kolon er endret til understrekninger. Som for andre parametere er en del av metoden navn, det kan ikke endres for å passe koding stil eller et uttrykk som med ekte navngitte parametre.
Imidlertid interne navn på funksjonen er sjelden brukt direkte. Generelt, meldinger blir konvertert til funksjonskall som er definert i Objective-C runtime library., Det er ikke nødvendigvis kjent på linken tid som metode vil bli kalt, fordi klassen av mottakeren (objektet blir sendt meldingen) det må ikke bli kjent før kjøring.
InstantiationEdit
Når en Mål-C-klasse er skrevet, det kan være lagt. Dette gjøres ved først å tildele en ikke initialisert forekomst av klassen (et objekt), og så ved å starte den. Et objekt er ikke fullt funksjonell til både tiltak har blitt gjennomført., Disse trinnene må gjøres med en linje med kode slik at det er aldri et tildelt objekt som ikke har gjennomgått initialisering (og fordi det er uklokt å holde mellomresultat siden -init
kan vende tilbake til et annet objekt enn det som det kalles).,
Oppretting med standard, ikke-parameteren initializer:
MyObject *foo = init];
Oppretting med en tilpasset initializer:
MyObject *foo = initWithString:myString];
I det tilfelle hvor ingen tilpasset initialisering utføres, den «nye» metoden kan ofte brukes i stedet for alloc-init meldinger:
MyObject *foo = ;
Også, noen klasser implementere klasse metode initializers., Liker +new
, de kombinerer +alloc
og -init
, men i motsetning til +new
, de kommer tilbake en autoreleased eksempel. Noen av klassens metode initializers ta parametere:
MyObject *foo = ;MyObject *bar = ;
alloc melding tildeler nok minne til å holde alle forekomsten variabler for et objekt, sett alle forekomsten variabler for å null-verdier, og blir minnet inn i en forekomst av klassen; ikke på noe punkt under initialiseringen er minnet en forekomst av superclass.,
init meldingen utfører satt opp for eksempel ved etableringen. Init-metoden er ofte skrevet som følger:
- (id)init { self = ; if (self) { // perform initialization of object here } return self;}
I eksempelet ovenfor, legg merke til id
gå tilbake type. Denne typen står for «peker til et objekt» i Objective-C (Se de Dynamiske å skrive avsnitt).
initializer mønsteret er brukt for å sikre at objektet er riktig initialisert av sin superclass før init-metoden utfører sine initialisering., Den utfører følgende handlinger:
- selvstendig = Sender superclass eksempel en init melding og gir resultatet til deg selv (pekeren til det aktuelle objektet).
- hvis (selv)Sjekker om det returnerte objektet pekeren er gyldig før du utfører noen initialisering.
- gå tilbake selfReturns verdien av selvet til den som ringer.
En ikke gyldig objekt pekeren har verdien null; betinget utsagn som «hvis» behandle nil som en null-peker, så initialisering koden ikke vil bli henrettet hvis det returneres null., Hvis det er en feil i initialisering init-metoden, bør du utføre alle nødvendige opprydding, herunder å sende en «release» – melding til deg selv, og gå tilbake nil-for å angi at mislyktes. Noen kontrollere for slike feil må bare utføres etter å ha kalt superclass initialisering for å sikre at ødelegge objektet vil bli gjort på riktig måte.
Hvis en klasse som har mer enn én initialisering metode, og bare én av dem («utpekt initializer») behov for å følge dette mønsteret, andre bør ringe det angitte initializer i stedet for superclass initializer.,
ProtocolsEdit
I andre programmeringsspråk, disse er kalt «grensesnitt».
Objective-C, ble utvidet på Neste for å introdusere begrepet multippel arv av spesifikasjonen, men ikke gjennomføring, gjennom innføring av protokoller. Dette er et mønster oppnåelig enten som en abstrakt flere arvet base class i C++, eller som en «interface» (som i Java og C#). Objective-C, gjør bruk av ad-hoc-protokoller kalt uformell protokoller og kompilator-tvungen protokoller kalt formelle protokoller.,
En uformell protokollen er en liste over metoder for at en klasse kan velge å implementere. Det er angitt i dokumentasjonen, siden det har ingen tilstedeværelse i språket. Uformell protokoller er implementert som en kategori (se nedenfor) på NSObject og ofte valgfrie metoder, som, hvis gjennomført, kan endre oppførselen til en klasse. For eksempel, en tekst-felt klasse kan ha en representant som implementerer en uformell protokoll med en ekstra metode for å utføre en auto-fullføring som brukeren har skrevet inn tekst., Tekstfeltet oppdager om representanten redskaper som metode (via refleksjon) og, hvis så, samtaler representanten metode for å støtte autofullfør-funksjonen.
En formell protokoll er lik et grensesnitt i Java, C#, og Ada-2005. Det er en liste over metoder som noen klasse kan erklære seg til å implementere. Versjoner av Objective-C, før 2.0 kreves at en klasse må implementere alle metodene i en protokoll det erklærer seg selv som å vedta; kompilatoren vil gi en feilmelding hvis klassen ikke implementerer hver metode fra sin erklærte protokoller. Objective-C, 2.,0 lagt til støtte for merking av visse metoder i en protokoll valgfritt, og kompilatoren vil ikke håndheve gjennomføring av valgfrie metoder.
En klasse må bli erklært for å gjennomføre denne protokoll sies å samsvare med det. Dette kan påvises ved kjøring. Formell protokoller kan ikke gi noen implementasjoner; de bare sikre innringere at klasser som er i samsvar med den protokollen vil gi implementeringer. I Neste/Apple-biblioteket, protokoller er ofte brukt av den Distribuerte Objekter system for å representere evner av et objekt gjennomføre på et eksternt system.,
kommandoen
@protocol NSLocking- (void)lock;- (void)unlock;@end
angir at det er den abstrakte ideen om låsing. Ved å si i klassen definisjon at protokollen er implementert,
@interface NSLock : NSObject <NSLocking>// ...@end
forekomster av NSLock hevder at de vil gi en løsning for de to eksempel metoder.
Dynamisk typingEdit
Objective-C, som Smalltalk, kan bruke dynamiske å skrive: et objekt kan bli sendt en melding som ikke er spesifisert i grensesnittet., Dette kan gi rom for økt fleksibilitet, som gjør at et objekt for å «fange» en melding og sende meldingen til et annet objekt som kan svare på meldingen på riktig måte, eller på samme måte sende meldingen til et annet objekt. Dette problemet er kjent som melding videresending eller delegering (se nedenfor). Alternativt, en feilbehandleren kan brukes i tilfelle meldingen ikke kan bli sendt. Hvis et objekt ikke videresende en melding, kan du svare på det, eller håndtere en feil, så vil systemet generere en runtime unntak., Hvis meldingene sendes til null (null object pekeren), vil de være stille ignorert eller høyne et generelt unntak, avhengig av kompilatoren valg.
Statisk typing informasjon kan eventuelt også legges til variabler. Denne informasjonen blir deretter kontrollert på kompilere tid. I følgende fire utsagn, i økende grad bestemt type informasjon er gitt. Uttalelsene er tilsvarende ved kjøring, men den ekstra informasjonen gir kompilatoren til å advare programmerer hvis gått argumentet ikke samsvarer med den typen som er angitt.,
- (void)setMyValue:(id)foo;
I ovennevnte uttalelse, foo kan være av hvilken som helst klasse.
- (void)setMyValue:(id<NSCopying>)foo;
I ovennevnte uttalelse, foo kan være en forekomst av enhver klasse som oppfyller NSCopying
protokollen.
- (void)setMyValue:(NSNumber *)foo;
I ovennevnte uttalelse, foo må være en forekomst av NSNumber klasse.
- (void)setMyValue:(NSNumber<NSCopying> *)foo;
I ovennevnte uttalelse, foo må være en forekomst av NSNumber klasse, og det må være i henhold til NSCopying
protokollen.,
I Objective-C, og alle objekter er representert som pekere, og statisk initialisering er ikke tillatt. Den enkleste objekt er den type id (objc_obj *) poeng til, som bare har et isa-pekeren beskriver sin klasse. Andre typer fra C, som verdier og strukturer, er uendret fordi de ikke er en del av objektet system. Denne beslutningen er forskjellig fra C++ objekt modell, der strukturer og klasser er united.
ForwardingEdit
Objective-C, tillater sending av en melding til et objekt som ikke kan svare., Heller enn å svare eller bare slippe melding, et objekt kan videresende meldingen til et objekt som kan svare. Videresending kan brukes til å forenkle gjennomføringen av visse design mønstre, slik som observatør mønster eller proxy-mønster.
The Objective-C runtime angir et par av metoder i Objektet
Et objekt som ønsker å implementere videresending trenger bare å overstyre videresending metode med en ny metode for å angi videresending av atferd. Handlingen metode performv:: må ikke overstyres, som denne metoden bare utfører en handling basert på velgeren og argumenter., Legg merke til SEL
type, som er den type meldinger i Objective-C.
Merk: i OpenStep, Kakao, og GNUstep, brukte rammer i Objective-C, et ikke bruker Object-klassen. Den – (void)forwardInvocation:(NSInvocation *)anInvocation metoden for NSObject klasse brukes til å gjøre videresending.
ExampleEdit
Her er et eksempel på et program som viser det grunnleggende om videresending.
Speditør.h Speditør.m Mottakeren.h
#import <objc/Object.h>// A simple Recipient object.@interface Recipient : Object- (id)hello;@end
Mottaker.m
#import "Recipient.h"@implementation Recipient- (id)hello { printf("Recipient says hello!\n"); return self;}@end
main.,m
NotesEdit
Når kompilert med gcc, kompilatoren rapporter:
kompilatoren er rapportering poenget er gjort tidligere, at Speditøren ikke svare på hei-meldinger. I dette forholdet, det er trygt å ignorere advarselen siden videresending ble gjennomført. Kjører programmet gir dette resultatet:
$ ./a.outRecipient says hello!
CategoriesEdit
Under utformingen av Objective-C, en av de største bekymringene var vedlikehold av store kode baser., Erfaring fra strukturert programmering verden hadde vist at en av de viktigste måtene å forbedre koden var å bryte det ned i mindre biter. Objective-C, lånt og utvidet konseptet kategorier fra Smalltalk implementeringer for å hjelpe til med denne prosessen.
Videre, metoder innen en kategori er lagt til en klasse på kjøre-time. Dermed, kategorier tillater programmerere å legge metoder til en eksisterende klasse – åpen klasse – uten at du trenger å kompilere som klasse eller selv har tilgang til dets kildekode., For eksempel, hvis et system som ikke inneholder en stavekontroll i sin Streng implementering, det kunne legges uten å endre Strengen kildekoden.
Metoder innen kategoriene blir umulig å skille dem fra metodene i en klasse når programmet kjøres. En kategori som du har full tilgang til alle forekomst variabler i klassen, inkludert private variabler.
Hvis en kategori erklærer en metode med samme metode signatur som en eksisterende metode i en klasse, kategori ‘ s metode er vedtatt. Dermed kategorier kan ikke bare legge metoder til en klasse, men også erstatte eksisterende metoder., Denne funksjonen kan brukes til å fikse bugs i andre klasser ved å skrive sine metoder, eller for å forårsake en global endring til en klasse atferd innenfor et program. Hvis to kategorier har metoder med samme navn, men forskjellig metode signaturer, det er udefinert hvilken kategori er metoden er vedtatt.
Andre språk har forsøkt å legge til denne funksjonen på en rekke måter. TOM tok Objective-C system et skritt videre og lov for tillegg av variabler også. Andre språk har brukt prototype-baserte løsninger i stedet, er den mest bemerkelsesverdige å være Selvstendig.
C# og Visual Basic.,NET språk implementere overfladisk lignende funksjonalitet i form av utvidelse metoder, men disse mangler tilgang til den private variabler av klassen. Ruby og flere andre dynamiske programmeringsspråk se teknikken som «monkey lapp».
Logtalk implementerer et konsept av kategorier (som første-klasse enheter) som subsumes Objective-C, kategorier funksjonalitet (Logtalk kategorier kan også brukes som finkornet enheter av sammensetning når du definerer for eksempel nye klasser eller prototyper, i særdeleshet, en Logtalk kategori kan være nesten importert av en rekke klasser og prototyper).,
Eksempel bruk av categoriesEdit
Dette eksemplet bygger opp et Heltall klasse, ved å definere først en grunnleggende klasse med bare accessor metodene implementeres, og legger til to kategorier, Matematikk og Skjerm, som å utvide de grunnleggende klasse. Mens kategorier kan få tilgang til basen klasse private data medlemmer, det er ofte lurt å få tilgang til disse private data medlemmer gjennom accessor metoder, som bidrar til å holde kategorier som er mer uavhengig fra base klasse. Implementering av slike accessors er en typisk bruk av kategorier. En annen er å bruke kategorier for å legge til metoder for å basen klasse., Det er imidlertid ikke ansett som god praksis å bruke kategorier for underklassen overordnede, også kjent som monkey lapp. Uformell protokoller er implementert som en kategori på basen NSObject klasse. Konvensjonen er filer som inneholder kategorier som strekker base klasser vil ta navnet BaseClass+ExtensionClass.h.
Heltall.h
#import <objc/Object.h>@interface Integer : Object { int integer;}- (int)integer;- (id)integer:(int)_integer;@end
Heltall.m Heltall+Matematikk.h
#import "Integer.h"@interface Integer (Arithmetic)- (id) add: (Integer *) addend;- (id) sub: (Integer *) subtrahend;@end
Heltall+Matematikk.m Heltall+Vis.h
#import "Integer.h"@interface Integer (Display)- (id) showstars;- (id) showint;@end
Heltall+Vis.m viktigste.,m
NotesEdit
Samling er utført, for eksempel ved å:
gcc -x objective-c main.m Integer.m Integer+Arithmetic.m Integer+Display.m -lobjc
En kan eksperimentere ved å legge ut #import «Integer+Matematikk.h» og linjer og utelate Heltall+Matematikk.m i samling. Programmet vil fortsatt kjøre. Dette betyr at det er mulig å mix-og-match lagt kategorier hvis nødvendig; hvis en kategori ikke trenger å ha noen mulighet, det kan rett og slett ikke være kompilere i.
PosingEdit
Objective-C, tillater en klasse helt erstatte en annen klasse innen et program. De bytte klasse sies å «posere som» målet klasse.,
Klasse poserer ble erklært ugyldige med Mac OS X v10.5, og er tilgjengelig i 64-bit runtime. Lignende funksjonalitet kan oppnås ved hjelp av metode swizzling i kategorier, som bytteavtaler en metode for implementering med en annen som har samme signatur.
For versjoner støtter fortsatt stille, alle meldinger som er sendt til målet klasse er i stedet mottar ved å stille klasse. Det er flere begrensninger:
- En klasse kan bare posere som en av sine direkte eller indirekte superclasses.,
- poserer klasse må ikke definere et nytt eksempel variabler som er fraværende fra mål-klasse (selv om det kan definere eller overstyre metoder).
- målet klasse, kan ikke ha mottatt noen meldinger før poserer.
Poserer, i likhet med kategorier, kan global utvidelse av eksisterende klasser. Poserer tillater at to funksjoner fraværende fra kategorier:
- En poserer klasse kan ringe overstyres metoder gjennom super, og dermed innlemme implementering av mål-klasse.
- En poserer klasse kan overstyre metoder definert i kategorier.,
For eksempel,
Dette avskjærer hver gang setMainMenu å NSApplication.
#importEdit
I C-språk, #include
pre-kompilere direktivet fører alltid til en fil innhold for å settes inn i en kilde på det tidspunktet. Objective-C, har #import
direktiv, tilsvarende, bortsett fra at hver fil er bare inkludert en gang per samling enhet, obviating behovet for å inkludere vakter.