Objective-C Ryhmä 35: Ilpo Kärki Aleksi Pälä
Sisällysluettelo 1 Yleistä...3 1.1 Lyhyesti...3 1.2 Historiaa...3 1.3 Hybridikieli...3 2 Muistinhallinta...5 2.1 Manual Retain Release (MRR)...5 2.2 Automatic Reference Counting (ARC)...5 3 Ominaisuudet...7 3.1 Luokat...7 3.2 Viestinvälitys...7 3.3 Kategoriat...7 3.4 Protokollat...7 4 Objective-C vs. C++...8 Lähteet...9 2
1 Yleistä 1.1 Lyhyesti Objective-C on yleiskäyttöinen, olio-ohjelmointiin perustuva ohjelmointikieli. Se on Applen Mac OS X ja ios laitteiden pääohjelmointikieli. C++:n tavoin sen tarkoituksena oli tuoda olio-ohjelmoinnin periaatteita C-kieleen, kuitenkin käyttäen huomattavasti erilaista lähestymistapaa[1]. Objective-C rakentuu C:n päälle ja kaikki C-kielen ohjelmat voidaankin kääntää Objective-C kääntäjällä[2]. Näin Objective-C:n luokkiin voidaan helposti lisätä C-kielen koodia. Kieli noudattaa C:n syntaksia kaikilta niiltä osin, jotka eivät liity olio-ohjelmointiin. Olio-ohjelmointiin liittyvät osat puolestaan muistuttavat Smalltalk-ohjelmointikielen viestinvälitystä, jossa olioiden metodeja ei kutsuta, vaan niille lähetetään viestejä. Objective-C:n tiedostopäätteenä toimii otsikkotiedostoissa.h ja toteutustiedostoissa.m. 1.2 Historiaa Objective-C:n synty juontaa juurensa 1980-luvulle. Ohjelmoijat Brad Cox ja Tom Love halusivat tehdä koodin uudelleenkäytettävyydestä osan ohjelmistokehitystä. Tähän tavoitteeseen päästäkseen he päättivät käyttää oman kielensä pohjana Smalltalk-ohjelmointikieltä, joka on yksi ensimmäisistä olio-ohjelmointiin perustuvista kielistä[3]. Yhteensopivuutta C-kielen kanssa pidettiin äärimmäisen tärkeänä, joten he alkoivat myös työstää esikääntäjää, jonka toisi Smalltalkin oliopiirteitä C-ohjelmointiin. 1988 Steve Jobsin johtama NeXT lisensoi Objective-C:n omaan käyttöönsä ja lisäsi GCCkääntäjään mahdollisuuden kääntää myös Objective-C:llä kirjoitettua koodia. NeXT käytti Objective-C:tä rakentaakseen oman NeXTSTEP-käyttöjärjestelmänsä. Vuonna 1996 Apple osti NeXTin ja päätti käyttää sen luoman NeXTSTEPin koodipohjaa luomaan oman uuden käyttöjärjestelmänsä[4]. Näin Objective-C:stä tuli keskeinen osa Applen Mac OS X- käyttöjärjestelmää. Samaa koodipohjaa käytettiin myös luomaan käyttöjärjestelmät Applen ios mobiililaitteille. 1.3 Hybridikieli Objective-C on hybridi kahden kielen välillä, joista molemmat kuuluvat erilaisiin paradigmoihin. Tämä hankaloittaa sen kategorisointia. C lähtöisyyden perusteella Objective-C:n voidaan katsoa kuuluvan imperatiivisen ohjelmoinnin -paradigmaan tai strukturoidun ohjelmoinnin paradigmaan. 3
Objective-C:n olio-ohjelmointiin liittyvät ominaisuudet luotiin Smalltalkin pohjalta, joten se on myös osa olio-ohjelmoinnin paradigmaa. Nämä paradigmat näkyvät selkeästi Objective-C ohjelmien rakenteessa ja toteutuksessa. Ohjelmien varsinainen rakenne ja kulku on toteutettu käyttäen C- kielen ominaisuuksia. Smalltalkilta perittyjä olio-ohjelmoinnin ominaisuuksia käytetään puolestaan kun määritellään ja käytetään abstrakteja, oliopohjaisia, rakenteita. Objective-C käyttää muiden C-sukuisten kielten tapaan staattista tyypitystä muuttujien tyypitykseen. Muuttujat täytyy siis esitellä, niille tulee antaa tyyppi eikä niiden tyyppi voi ajon aikana muuttua. Olioiden kanssa toimimiseen Objective-C tarjoaa kuitenkin mahdollisuuden käyttää dynaamista tyypitystä. Tämä toteutetaan tyypin id avulla. Id on osoitin, joka voi osoittaa mihin tahansa olioon, tyypistä huolimatta[5][6]. Id tyypin avulla mahdollistetaan myös dynaaminen sidonta. Voimme siis luoda funktion, joka ottaa parametrikseen objektin, ja joka kutsuu tuon objektin jäsenfunktiota. Käyttämällä parametrin tyyppinä id:tä voimme olla varmoja, että funktio kutsuu oikean olion jäsenfunktiota. Tästä voi kuitenkin aiheutua ongelmia, koska tyyppitarkastelut tehdään ajon aikana. Näin ollen, jos parametrina annettu olio ei sisälläkään kutsuttua funktiota, tapahtuu ajonaikainen virhe ja ohjelma mahdollisesti kaatuu. Tämä voidaan estää käyttämällä Objective-C:n tukemaa viestien eteenpäin lähetystä, jonka avulla voidaan määrittää olion käyttäytyminen, jos se saa viestin jota se ei osaa käsitellä. 4
2 Muistinhallinta Objective-C sallii kahden erilaisen muistinhallintamenetelmän käyttämisen. Manual Retain Release-menetelmässä ohjelmoija itse huolehtii olioiden omistussuhteiden hallinnasta erilaisten funktioiden avulla. Xcode kehitysympäristön versiosta 4.2 eteenpäin ohjelmoijille on tarjottu mahdollisuus käyttää Automatic Reference Counting-menetelmää, jossa ohjelmoijan ei tarvitse huolehtia olioiden omistussuhteista itse, vaan se hoituu automaattisesti. ARC-menetelmän käyttöä suositellaan[7]. Molemmat menetelmät on esitelty omissa kappaleissaan. 2.1 Manual Retain Release (MRR) Käytettäessä Manual Retain Release (manuaalinen omistus ja vapautus, tästä eteenpäin MMR) ympäristöä ohjelmoijan täytyy itse huolehtia olioiden omistussuhteiden hallinnasta. Tämä onnistuu alla kuvatuilla muistinhallintaan tarkoitetuilla metodeilla[8]. Metodi Toiminta alloc Luo olion ja asettaa sille omistussuhteen retain Asettaa omistussuhteen olemassa olevalle oliolle copy Kopioi olion ja asettaa sille omistussuhteen release Vapauttaa olion omistussuhteesta ja tuhoaa sen välittömästi autorelease Vapauttaa olion omistussuhteesta, mutta ei tuhoa sitä Taulukko 1: Taulukko 1. Objective-C:n muistinhallintaan tarkoitetut metodit. Objective-C:n muistinhallinta perustuu viitteiden laskemiseen. Kun oliolle asetetaan omistussuhde (alloc, retain, copy) kasvaa viitteiden määrä yhdellä. Kun omistussuhde poistetaan (release, autorelease), laskee viitteiden määrä yhdellä. Olioon osoittavien viitteiden määrän laskiessa nollaan, ei yksikään toinen olio sano enää omistavansa olioa ja sen käyttämä muisti voidaan vapauttaa. Tämän menetelmän käyttämisestä aiheutuu se, että jokaista olioon kohdistettua alloc, retain tai copy kutsua kohden täytyy muistaa kutsua yhtä monta release tai autorelease kutsua. Jos viitteiden määrää ei pienennetä tarpeeksi, jää ohjelmaan ylimääräistä käyttämätöntä muistia, eli aiheutuu muistivuotoja. Jos taas olioita vapautetaan liian aikaisin, saatetaan suorittaa haku jo vapautettuun ja virheelliseen muistipaikkaan. 2.2 Automatic Reference Counting (ARC) Automatic Reference Countin (automaattinen viitteiden laskeminen, tästä eteenpäin ARC) toimii täysin kuten MMR, mutta sitä käytettäessä ohjelmoijan ei itse tarvitse huolehtia muistinhallintaan liittyvien metodien kutsumisesta. ARC analysoi kirjoitetun koodin ja selvittää olioiden elinajan. Tekemänsä analyysin perusteella se 5
asettaa koodiin tarvittavat retain, release ja autorelease kutsut. ARC:tä käytettäessä koodiin ei itse voi laittaa kyseisiä kutsuja. Sen sijaan alloc ja copy kutsuja voidaan käyttää. 6
3 Ominaisuudet 3.1 Luokat Luokat Objective-C:eessä toimivat kuten monissa muissakin kielissä, niillä on metodeja ja muuttujia. Luokkien rajapinta esitellään otsikkotiedostossa ja toteutus toteutustiedostossa. Kaikki luokat on periytetty muista luokista tai suoraan juuriluokasta(nsobject). Objective-C luokan kaikki metodit ovat julkisia, eikä yksityisiä metodeja pysty luomaan. Metodeja on kuitenkin mahdollista piilottaa erilaisilla tavoilla, mutta metodi ei ole kuitenkaan koskaan täysin saavuttamattomissa luokan ulkopuolelta. Muuttujat voivat olla julkisia, suojeltuja tai yksityisiä. 3.2 Viestinvälitys Objective-C:eessä ei kutsuta luokan metodeja kuten C++:ssa. Objective-C:essa sen sijaan lähetetään viestejä objekteille mikä toimii osittain metodikutsujen tapaan, mutta dynaamisesti. Kääntäjä luo käännösaikasesti luokalle taulukon sen sisältämistä metodeista ja tiedon sen kantaluokasta. Kun objekti vastaanottaa viestin se vertaa sitä sen metodi taulukkoon, jos metodi löytyy niin se suoritetaan, jos metodia ei kuitenkaan löydy välitetään viesti kantaluokalle, tätä jatketaan kunnes löydetään metodi tai päästään juuriluokkaan(nsobject), joka luo poikkeuksen[9]. Luokalle on myös mahdollista toteuttaa käsittelijä tunnistattomille viesteille ylikirjoittamalla muutama juuriluokan metodi jotka normaalisti loisivat poikkeuksen, näin on mahdollista estää poikkeuksien synty[10]. 3.3 Kategoriat Yksi tärkeimpiä mietinnän kohteita Objective-C:n suunnittelussa oli miten koodista saataisiin mahdollisimman helposti ylläpidettävää. Tähän ratkaisuna nähtiin sekä koodin uudelleen käytettävyys, että koodin jakaminen mahdollisimman pieniin palasiin. Kategorioiden avulla Objective-C:hen tuotiin mahdollisuus laajentaa jo olemassa olevia luokkia. Kategorioiden tuomat laajennukset lisätään luokkiin ajon aikana, joten vanhoja luokkia ei tarvitse edes kääntää uudelleen. Jos kategorian sisällä määritellään samanniminen metodi kuin minkä luokka itsessään jo sisältää, ei ole määritelty kumman toteutusta käytetään[11]. 3.4 Protokollat Protokollien avulla Objective-C:ssä on mahdollista toteuttaa eräänlaista moniperintää. Protokolla luodaan samaan tapaan kuin normaalisti luokalle luotavat rajapinnat. Sen sisällä määritellään metodit, jotka sen käyttöön ottavan luokan täytyy toteuttaa. Luokka voi ottaa käyttöön useita eri protokollia, mutta sen tulee toteuttaa niiden kaikkien määrittelemät metodit. 7
4 Objective-C vs. C++ Lähin vertailukohde Objective-C:lle on toinen C:tä olio-ohjelmointiin laajentanut kieli C++. Kielet eroavat kuitenkin suuresti siinä, miten ne ovat tämän toteuttaneet. Objective-C toi olio-ohjelmoinnin C:hen käyttäen olioiden välistä viestinvälitystä. C++ puolestaan käyttää olioiden kutsumiseen niiden metodeja. C++:ssa metodi sidotaan luokkaan kääntämisen yhteydessä. Objective-C:ssä sidonta tapahtuu ajon aikana. Käännösaikaisen sidonnan käyttäminen on ohjelman suorituksen kannalta nopeampaa. Dynaamisen sidonnan etuna on kuitenkin se, että viestin vastaanottajaa ei tarvitse tietää, eikä täydy olla varma että vastaanottajalla on kyky käsitellä viestiä. Tämän avulla voidaan esimerkiksi lähettää viestejä isolle joukolle olioita, joista kaikki eivät välttämättä osaa käsitellä viestiä. Viestin vastaanottajan täytyy kuitenkin osata käsitellä tapaus, jossa se saa viestin jonka toiminnallisuutta se ei toteuta. Muuten tapahtuu ajonaikainen virhe ja suoritus voi keskeytyä. Objective-C++ on yritys tuoda C++:aan samat ominaisuudet, jotka Objective-C lisäsi C:hen. 8
Lähteet [1] http://rypress.com/tutorials/objective-c/introduction [2] http://www.technobuffalo.com/2011/03/27/introduction-to-ios-development-an-overview-of-objective-c/ [3] http://www.techotopia.com/index.php/the_history_of_objective-c [4] https://www.binpress.com/tutorial/objectivec-a-brief-history/37 [5] https://www.binpress.com/tutorial/learn-objectivec-objects-part-8-dynamic-typing/68 [6] http://www.techotopia.com/index.php/objective-c_dynamic_binding_and_typing_with_the_id_type [7] https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/memo rymgmt.html [8] http://code.tutsplus.com/tutorials/objective-c-succinctly-memory-management--mobile-21996 [9] http://blog.imaginea.com/message-forwarding-and-surrogate-objects-in-objective-c/ [10] http://blog.paulopoiati.com/2009/12/05/forwarding-objective-c-messages/ [11] https://developer.apple.com/library/ios/documentation/cocoa/conceptual/programmingwithobjectivec/ CustomizingExistingClasses/CustomizingExistingClasses.html 9