Grafikus interfészt használó program

BecomeAnXcoder – Grafikus interfészt használó program

Bevezető

Most már elegendő Objective C ismeretünk van ahhoz, hogy elkezdjük a grafikus felhasználói felülettel (GUI) rendelkező programok írását. Be kell vallanom most valamit. Az Objectve C valójában a C nevű programozási nyelv kiterjesztése. Amiről idáig beszéltünk, az szinte minden a C nyelvről szólt. Tehát akkor miben is különbözik egymástól a két nyelv? A különbség az “Objective” részben keresendő. Az Objective C az absztrakt objektumok fogalmával operál.

Idáig inkább csak számokkal dolgoztunk. Ahogy megtanultuk, az Objective C alapvetően támogatja a szám fogalmát. Ez azt jelenti, hogy lehetőség van számokat létrehozni a memóriában és matematikai műveletekkel, függvényekkel operálhatunk rajtuk. Ez nagyszerű, amikor a programod számokkal dolgozik (mint például egy számológép esetében), de mi a helyzet ha zeneszámokat tároló programot kell fejleszteni, ami zeneszámokkal, címlistákkal, művészekkel kell, hogy operáljon? Vagy mi a helyzet, ha egy repülésirányítási rendszer fejlesztése a cél, ahol repülőgépek, járatok, repülőterek az alapvető objektumok? Vajon lehetséges lenne, hogy az Objective C-ben ezekkel a dolgokkal ugyanolyan egyszerűen bánjunk, mint a számokkal?

Éppen ez a dolog lényege. Az Objective C segítségével olyan típusú objektumokat tudsz definiálni, amilyenekre szükséged van és olyan alkalmazásokat tudsz írni, amelyek képesek ezekkel az objektumokkal dolgozni.

Objektumok akció közben

Példaképpen nézzük meg, hogyan is kezelünk egy ablakot egy Objective C-ben megírt program esetében. Ilyen például a Safari. Vessünk egy pillantást egy nyitott Safari ablakra a Mac-en. A bal felső sarokban van három gomb. A piros az ablak bezáró gomb. Mi történik, amikor bezárunk egy Safari ablakot úgy, hogy rákattintunk erre a kis piros gombra? Egy üzenetet küldünk az ablaknak. Válaszképpen erre az üzenetre az ablak lefuttat egy kis programkódot annak érdekében, hogy bezárja magát.

09 Object Action

A bezár üzenet el lett küldve az ablaknak

Az ablak egy objektum. Körül tudod rajzolni. A három gomb szintén egy-egy objektum. Rájuk tudsz klikkelni. Ezeknek az objektumoknak van vizuális megfeleltetése a képernyőn, de nem feltétlenül igaz ez minden objektumra. Például annak az objektumnak, amelyik kapcsolatot létesít a Safari és egy adott web oldal között, nincs vizuális megvalósítása a képernyőn.

10 Object Buttons

Egy objektum (például az ablak) tartalmazhat más objektumokat (mint például a gombok)

Osztályok

Annyi Safari ablakot tudsz megnyitni amennyit csak akarsz. Mit gondolsz, az Apple programozói:

      (a) leprogramozták az összes ablakot előre,
            kihasználva messzeföldről híres képzelőerőjüket,
            hogy neked hány darab ablakra lesz majd szükséged, vagy

        (b) készítettek egy mintát és megkérték a Safarit,
            hogy menet közben hozza létre neked ezeket az ablakokat?

Természetesen a helyes válasz a (b). Készítettek egy speciális kódot, amit osztálynak nevezünk és ez leírja, hogy mi az az ablak, hogyan néz ki és hogyan működik. Amikor készítesz egy új ablakot, akkor valójában ez az osztály készíti el az új ablakot. Ez az osztály tartalmazza az ablak leírását és mindegyik konkrét ablak ennek az osztálynak egy példánya (ugyanúgy, ahogy a 76 egy példánya a számok osztályának).

Változó példányok

Az általad megnyitott ablaknak van egy aktuális meghatározott helye a Mac képernyőjén. Amennyiben lekicsinyíted és a Dock-ba rakod, majd visszanyitod, akkor pontosan ugyanazt a pozíciót fogja a elfoglalni a képernyőn, mint korábban. Hogyan lehetséges ez? Az osztály definiál arra alkalmas változókat, amelyek megjegyzik az ablak képernyőn elfoglalt pozícióját. Az osztály példánya, azaz az objektum tartalmazza ezen változók aktuális értékét. Tehát minden ablak objektum tartalmaz bizonyos változó értékeket és különböző ablakok esetében általában más- és más értéket vesznek fel ugyanazok a változók.

Metódusok

Az osztály nem csak az ablak objektumot készítette el, hanem lehetőséget biztosít számára különböző akciók végrehajtására is. Az egyik ilyen művelet a bezárás. Amikor az ablak “Close” gombjára kattintasz, a gomb küld egy bezárás üzenetet az ablak objektuktumnak. Az objektum által elvégezhető műveleteket metódusoknak nevezzük. Ahogy láthatod, itt sok minden nagyon hasonlít a függvényekről tanultakra, tehát nem lesz nehéz dolgod a tanulásban feltéve, hogy eddig pontosan követtél minket.

Objektumok a memóriában

Amikor az ablak készít egy ablak objektumot számodra, akkor lefoglal részére egy memória (RAM) területet ahol tárolja az ablak pozícióját és más információkat. Azonban nem készít minden esetben egy újabb kódsorozatot az ablak bezárásának műveletére. Ez pazarlás lenne a számítógép memóriájával, mivel ez a kód minden egyes esetben ugyanaz. Az ablak bezárásának utasítássorozatát elegendő egyszer tárolni és lehetővé kell tenni, hogy az ablak osztályának minden ablak objektuma hozzáférhessen ahhoz.

Mint korábban is, ebben a fejezetben is lesznek olyan kódrészletek, amelyek a memória foglalással és felszabadítással foglalkoznak, de ahogy korábban is említettük, ezekkel mélyebben most még nem foglalkozunk, csak sokkal később. Bocsánat.

Gyakorlat

Az alkalmazásunk

Készítünk egy kis alkalmazást két gombbal és egy szövegmezővel. Ha megnyomod az egyik gombot, akkor megjelenik egy szám a szövegmezőben. Ha megnyomod a másik gombot, akkor egy másik szám jelenik meg a szövegmezőben. Elképzelhetjük úgy is mint egy két gombos számológép, amelyik számításokat nem tud végezni. Természetesen amikor majd többet fogsz tudni, azt is kitalálod majd, hogyan lehet valóságos számításokat végeztetni, de jobban szeretem a kis lépésekben való haladást.

11 Our App

Az eltervezett alkalmazás vázlata

Amikor az egyik gombot megnyomjuk, az küld egy üzenetet. Ez az üzenet tartalmazza annak a metódusnak a nevét, amit végre kell hajtani. Ez az üzenet el lesz küldve, de hova is? Az ablak esetében a bezárás üzenet annak az ablak objektumnak volt elküldve, amelyik az ablak osztály megfelelő példánya. Most tehát egy olyan objektumra lesz szükségünk, amelyik képes üzeneteket fogadni mindkét gombtól, és meg tudja mondani a szövegmező objektumnak, hogy jelenítsen meg egy adott értéket.

Az első osztályunk

Nos, mindenekelőtt el kell készítenünk egy osztályt, majd annak egy példányát. Ez az objektum fogja fogadni a gombok által küldött üzeneteket. (Kérlek ellenőrizd a lenti vázlatot.) Ugyanúgy, mint egy ablak objektum ez a példány is egy objektum, de az ablak objektummal szemben most nem látjuk a példányunkat a képernyőn futás közben. Ez csak a Macintosh memóriájának egy szelete lesz.

Amikor a példányunk megkapja a két gomb közül valamelyik által küldött üzenetet, a megfelelő metódus lefut. Ennek a metódusnak a programkódja az osztályban található (nem a példányban magában). A végrehajtás során ez a metódus reszeteli (alapállapotba állítja) a szöveget a szövegmező objektumban.

Honnan tudja a metódus az osztályunkban hogyan kell reszetelni a szöveget a szövegmezőben? Jelenleg ezt sehonnan nem tudja. De a szövegmező tudja, hogyan lehet reszetelni a saját szöveg tartalmát. Tehát egyszerűen küldünk egy üzenetet a szövegmező objektumnak, és megkérjük, hogy tegye meg ezt nekünk. Milyen típusú üzenetnek kell ennek lennie? Természetesen pontosan meg kell neveznünk a címzettet (azaz a szövegmező objektumot az ablakunkban). Ezen kívül meg kell mondani az üzenetben, hogy mit kérünk a címzettől. Ezt úgy tesszük, hogy megmondjuk annak a metódusnak a nevét, amit a szövegmezőnek futtatni kell amikor értelmezi az üzenetet. (Természetesen tudnunk kell milyen metódusokat tud futtatni a szövegmező és hogyan hívják őket.) Azt is közölnünk kell a szövegmező objektummal, hogy milyen értéket kell megjeleníteni (annak függvényében, hogy melyik gombot nyomtuk meg). Tehát az üzenet által közvetített kifejezés nem csupán a objektum és metódus nevét tartalmazza, hanem van egy argumentuma is, azaz egy paramétert is közvetít, amit a szövegmező objektum metódusának kell majd használnia.

12 Our Class

Az alkalmazásunk objektumai közötti üzenetváltások vázlata

Most megmutatjuk hogyan küldünk üzenetet az Objective C-ben paraméter nélkül [1.1] és paraméterrel[1.2]:

//[1]
 [receiver message]; //[1.1]
 [receiver messageWithArgument:theArgument]; //[1.2]

Mindkét utasításra jellemző, hogy szögletes zárójelek foglalják egységbe és a már jól ismert pontosvessző zárja le őket. A zárójelek között először a cél objektumot kell megnevezni, és ezt követi az objektum egyik metódusa. Amennyiben a meghívott metódus kötelezően egy, vagy több értéket is vár, akkor azt is meg kell adni [1.2].

Projekt készítés

Most nézzük meg hogyan is működik ez a valóságban. Indítsuk el az Xcode programot, hogy készíthessünk egy új projektet. Válasszuk ki a Cocoa Application-t a Mac OS X Application menüből. Adjunk egy nevet, amit GUI alkalmazások esetében nagy betűvel szoktunk kezdeni. Az Xcode Groups & Files ablakában nyissuk ki a Resources (források) foldert. Kattintsunk kétszer a MainMenu.xib fájlra.

13 Xcode Nib

Kattintsunk kétszer a MainMenu.xib fájlra az Xcode-ban

Az Xcode 3 előtt a xib fájlok végződése nib volt, ami a NeXT Interface Builder rövidítéséből származott. Ezért ha az Xcode-nak egy korábbi verzióját használod, akkor ott esetleg a MainMenu.nib fájlt kell megnyitnod. Ez egy lényegtelen különbség, minden más pontosan ugyanúgy működik.

GUI készítés

Ekkor elindul egy másik program, az Interface Builder (IB). Mivel több ablak is megnyílik, szükség esetén használhatod a Hide Other (elrejti a többit) opciót a File menüben. Három ablakot fogsz látni. Az egyik neve a “Window”, ez lesz az az ablak, amit az alkalmazásod használója látni fog. Mellette ott látható a Library ablak. Ez az összes olyan objektum tárháza, amelyeket használhatsz a grafikus interfészedben, ezt könyvtár palettának is szokás nevezni. Válaszd ki a “Views & Cells”-t ennek az ablaknak a felső listájából és húzzál át két gombot egyesével a GUI ablakba: “Window”. Hasonlóan húzzál egy szöveg mezőt (text Label) is a GUI ablakba.

14 Create Gui

GUI objectumok áthúzása a paletta ablakból az alkalmazás ablakba

Azzal, hogy áthúzunk egy gombot a paletta ablakból az alkalmazás ablakba háttérben készül egy új gomb objektum és az bekerül az ablakodba. Ugyanez történik a szövegmezővel és minden más objektummal, amit a palettáról áthúzunk az ablakba.

Megjegyezzük, hogy ha a paletta ablak egy ikonja felett tartod a kurzort, akkor egy név fog megjelenni, mint például NSButton, vagy NSTextView. Ez az Apple által szolgáltatott osztályoknak a neve. Hamarosan meg fogjuk mutatni, hogyan tudjuk megtalálni azokat a metódusokat ezekben az osztályokban, amelyeket használni akarunk a programunkban.

Ne felejtsd el rendszeresen menteni a xib (nib) fájlokat, mert az Xcode és az IB így szinkronban marad.

Rendezd el, méretezd át a “Window” ablakba húzott objektumokat ízlésednek megfelelően. Változtasd meg a gomb objektumokon levő szövegeket, ehhez kétszer rájuk kell kattintanod. Javaslom, hogy fedezd fel a paletta ablak tartalmát miután befejeztük ezt a projektet, hogy legyen egy elképzelésed arról, hogy a későbbiekben milyen objektumokat hogyan használhatsz még.

Ismerkedés az Interface Builder-rel (IB)

Ha kiválasztasz egy objektumot és megnyomod a Cmd-Shift-I billentyűkombinációt, akkor meg tudod változtatni a beállításokat. Gyakorold be ezt is. Például válaszd ki a “Window” ablakot (amit megtehetsz úgy is, hogy a xib ablakban rákattintasz egyszer) és nyomd meg a Cmd-Shift-I billentyűkonbinációt. Az Inspector tetején válaszd ki a Window Attributes-t. Itt jelöld be a Textured opciót és az ablakod máris fémes árnyalatú lesz. AZ IB erőssége abban rejlik, hogy az alkalmazásod megjelenítését nagyon sokféleképpen megváltoztathatod vele, ráadásul mindezt egyetlen programsor megírása nélkül!

15 Explore Ib

Az ablakunk az Interface Builder-ben, valamint a hozzá tartozó Inspector ablak

Osztály háttér

Ahogy megígértük korábban, létre fogunk hozni egy osztályt. De előtte még beszéljünk arról, hogyan működik egy osztály.

Nagyon sok programozási munkát meg lehet spórolni azáltal, ha lehetőségünk van arra, hogy mások által már elkészített dolgokat beépítsünk ahelyett, hogy mindent nekünk kellene megírni a legapróbb részletektől kezdve. Ha például szeretnél készíteni egy speciális tulajdonságokkal (képességekkel) rendelkező ablakot, csak az egyedi tulajdonságoknak megfelelő részeket kell hozzáadnod. Nem kell ismételten megírni a programkódot az összes viselkedésre, mint például az ablak minimalizálása, vagy az ablak bezárása. Ingyenesen beépítheted, örökölheted ezeket a más programozók által már megírt a tulajdonságokat. Pontosan ez az amiben az Objective C lényegesen eltér a sima C programozási nyelvtől.

Hogyan is működik ez valójában? Nos, itt van egy ablak osztály: NSWindow, te pedig tudsz írni egy olyan osztályt amelyik örökli ennek a tulajdonságait. Nézzük meg mi történik, ha ehhez hozzáadsz néhány saját tulajdonságot. Mi történik, ha a te ablakod kap egy “close“, azaz egy bezárás üzenete? Nem írtál semmi ilyen műveletet, és nem is másoltál át olyan kódokat, amelyek ezt végre tudnák hajtani. Ilyenkor, azaz amikor az adott ablak osztálya nem tartalmazza az adott metódust, az üzenet automatikusan továbbítódik ahhoz az osztályhoz, ahonnan a mi ablak osztályunk öröklődik, tehát az ő szuperosztályához (superclass). És ha szükséges, akkor továbbmegy odáig, amíg a metódust megtalálja (vagy eléri az öröklődési hierarchia csúcsát.)

Amennyiben a metódus nem található, akkor egy olyan üzenetet küldtél, ami nem végrehajtható. Ez olyan mintha megkérnénk egy autószervizt, hogy cseréljék ki a szánkónkon a kerekeket. Még a szerelőműhely főnöke sem tud ebben segíteni. Hasonló esetben az Objective C küld egy hibaüzenetet.

Saját osztályok

Mi történik, ha szeretnél saját tulajdonságokkal felruházni a szuperosztályból származó metódusokat? Erre is van lehetőség, felül lehet írni a metódusokat. Például írhatsz egy olyan programkódot, amelyik a bezárás gombra kattintva csak láthatatlanná teszi, ahelyett hogy véglegesen bezárná azt. A speciális ablak osztályod ugyanazt a metódus nevet kell, hogy használja, mint az Apple által definiálté. Ezért amikor a te speciális ablakod kap egy bezárás üzenetet, akkor a te metódusod fog lefutni és nem az Apple-é, ezért az ablak csak látókörön kívül kerül mielőtt teljesen bezáródna.

Figyelem, a végleges bezárás metódust az Apple leprogramozta. A mi saját bezárás metódusunk belsejéből még lehetséges meghívni az eredeti szuperosztályban levő metódust, mindamellett ezt egészen más formában kell megtenni annak érdekében, hogy a saját bezárás metódusunk ne kerüljön egy rekurzív ciklusba.

//[2]
// Ide kerül az ablakot láthatatlanná tevő kód. 
[super close]; // Használjuk a szuperosztály bezárás metódusát.

Ez a téma kicsit túlmutat jelen könyvünk keretein ezért nem várhatjuk el, hogy maradéktalan mindent megérts belőle.

Egy univerzális osztály

Az NSObject osztály a király az összes osztály között. Szinte az összes osztály amit írni, vagy használni fogsz, direkt, vagy közvetett módon az NSObject osztály alosztálya lesz. Például az NSWindow osztály az alosztálya az NSResponder osztálynak, amelyik az alosztálya az NSObject osztálynak. Az NSObject osztály közös metódusokat definiál az összes objektumnak (például az objektum szöveges leírását generálja, megkérdezi az objektumtól, hogy érti-e az adott üzenetet és így tovább.)

Mielőtt további unalmas elmélettel untatnálak, nézzük hogyan kell elkészíteni egy osztályt.

Az osztályunk elkészítése

Vegyük elő az Xcode projektünket és válasszuk ki a New File-t a File menüből. Válasszunk ki egy Objective-C osztályt a listából, majd kattintsunk a Next gombra. Nevezzük el például “MAFoo”-nek, majd kattintsunk a Finish gombra.

16 Subclass Mafoo

A MAFoo osztály készítése

A MAFoo név első két karaktere a My Application rövidítése. Természetesen bármilyen nevet kitalálhatsz, de amikor a saját alkalmazásaidat írod, feltétlenül javasoljuk, hogy az osztályod neve ugyanazzal a 2-3 karakterrel kezdődjön, mert így legkönnyebb elkerülni létező osztálynevekkel való ütközést. De semmiképpen se kezd őket az NS karakterekkel. Az Apple osztályai kezdődnek így. Ez a NeXTStep névből származik. A NeXTStep-ről érdemes tudni, hogy ez volt a Next cég által fejlesztett és használt operációs rendszer neve, amit az Apple megvásárolt és ez lett a Mac OS X alapja, valamint ráadásként Steve Jobs is visszakerült az Apple-höz.A CocoaDev wiki tartalmaz még egy sor ajánlást, hogy mivel ne kezdjünk osztályneveket. Feltétlenül tanulmányozd, mielőtt a saját osztálynevedet megválasztod: http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix

Az osztály nevét célszerű úgy megválasztani, hogy jellemző információkat tartalmazzon az osztályról magáról. Példaképpen vegyük a már ismert NSWindow Cocoa osztályt, amelyik az ablakot (window) reprezentálja. Egy másik példa a színeket reprezentáló osztály, aminek a neve NSColor. Esetünkben a MAFoo osztály azt mutatja be, hogyan tudnak az objektumok kommunikálni egymással egy alkalmazásban. Ezért adtunk neki egy általános nevet, mindenfajta speciális jelentés nélkül.

Egy példány készítése az Interface Builder-ben

Vegyük elő ismét az Interface Buildert és a library palettában a főmenüből válasszuk ki az Objects & Controllers-t. Ezután húzzunk egy objektumot (kék kocka) a palettáról a MainMenu.xib osztályra.

18 Instantiate

Egy új objektum példányosítása

Ezután válasszuk ki az Identity gombot az Inspector palettáról (Cmd-6), majd válasszuk ki a MAFoo osztályt a legördülő menüből. Ezzel a xib fájlunk egy objektumába példányosítottuk a MAFoo osztályunkat az Xcode-ban. Ez lehetővé fogja tenni, hogy a programkódunk és az interfészünk kommunikálni tudjon egymással.

19 Identity

Az objektum példányunk azonosságának beállítása

Kapcsolatok létrehozása

A következő lépésben kapcsolatokat létesítünk a gombok (ahonnan az üzenetek lesznek küldve) és a MAFoo objektum között. Ezen kívül létesítünk egy kapcsolatot a MAFoo objektumból vissza a szövegmezőhöz, mivel a szövegmező objektumnak is fogunk egy üzenetet küldeni. Egy objektum nem tud üzenetet küldeni egy másik objektumnak, amennyiben nem tartalmaz hivatkozást a másik objektumra. Amikor egy kapcsolatot létesítünk a gomb és a MAFoo osztály között, akkor ezt a gombot egy hivatkozással rendeljük hozzá a MAFoo objektumhoz. Ezt a hivatkozást használva, a gomb képes lesz arra, hogy üzenetet küldjön a MAFoo objektumunk számára. Hasonlóan, létrehozva egy kapcsolatot az objektumunkból a szövegmező objektumra, lehetővé teszi később az üzenetküldést.

Gondoljuk át még egyszer milyen alkalmazást kell fejlesztenünk. Mindkét gomb, ha rákattintunk, képes egy üzenetet küldeni az adott akciónak megfelelően. Ez az üzenet tartalmazza a MAFoo osztály azon metódusának a nevét, amit végre kell hajtani. Az üzenet a MAFoo osztály éppen most létrehozott példányának, a Mafoo objektumnak lesz elküldve. (Emlékeztetnénk, hogy az objektum példány nem tartalmazza az akció végrehajtásához szükséges programkódot, de az osztály igen.) Ezért a MAFoo objektumnak elküldött üzenet elindítja a MAFoo osztály egy metódusát, ami elvégzi a feladatot: jelen esetben küld egy üzenetet a szövegmező objektumnak. Mint minden üzenet, ez is tartalmazza a metódus nevét (amit a szövegmező objektumnak végre kell hajtani). Ebben az esetben a szövegmező objektum metódusának az a feladata, hogy megjelenítsen egy értéket. Ezt az értéket az üzenet részeként kellett elküldeni (ezt hívtuk argumentumnak, ugye emlékszel?) a szövegmezőn meghívott metódus nevével együtt.

Az osztályunknak szüksége van két műveletre (metódus), ami a két gomb objektum által lesz meghívva. Az osztályunknak szüksége lesz még egy outlet-re, egy változóra annak érdekében, hogy emlékezzen arra, melyik objektumnak lett elküldve az üzenet (az adott példában ez ugye a szövegmező objektum).

Győződj meg róla, hogy a MAFoo ki van választva a MainMenu.xib ablakban. A billentyűzeten nyomd meg a Cmd-6 kombinációt annak érdekében, hogy az Identity Inspector ablak legyen aktív. Ebben az ablakban, az Action részben kattints az Add (+) gombra, hogy hozzáadjunk egy akciót (azaz egy akció metódust) a MAFoo osztályhoz. Az Interface Builder által felajánlott nevet cseréljük ki egy beszédesebbre (például beírhatjuk a “setTo5:”-öt, hiszen azt fogjuk beprogramozni, hogy jelenítse meg az 5-ös számot a szövegmezőben). Adjunk egy másik metódust is a MAFoo osztályhoz és ne feledkezzünk meg a névadásról sem (például legyen ez a “reset:”, hiszen azt fogjuk beprogramozni, hogy jelenítse meg a 0 számot a szövegmezőben). Felhívjuk a figyelmet arra, hogy mindkét metódus név kettőspontra végződik. Erre majd még később visszatérünk.

Az Inspector ablakban kicsit lejjebb, most válasszuk ki az Outlet részt, adjunk hozzá egy új outletet és nevezzük is el (például “textField”).

18 Add Actions

A MAFoo osztályhoz akció és otlet metódusokat adunk hozzá

Mielőtt létrehozzuk az objektumok közötti kapcsolatokat, adjunk beszédes nevet a két gombnak. Mivel az elsőt arra szánjuk, hogy kérje meg a MAFoo példányunkat az 5-ös szám megjelenítésére a szövegmezőben, ezért ennek adjuk a “Set to 5″ nevet (már korábban láttuk, hogyan lehet a gomb nevét megváltoztatni: kétszer kattintsunk a nevére a képernyőn és írjuk be az új nevet). Hasonlóan nevezzük el a másikat “Reset”-nek. Megjegyezzük, hogy a gomboknak történő névadás nem szükséges a program korrekt működéséhez. Ennek csupán az a célja, hogy azt szeretnénk, ha a felhasználói felületünk a lehető legérthetőbb lenne a felhasználó számára.

Most már valóban készen vagyunk arra, hogy létrehozzuk az aktuális kapcsolatokat a

- a “Reset” gomb és a MAFoo példány
- a “Set to 5″ gomb és a MAFoo példány
- a MAFoo példány és a szövegmező

között.

A kapcsolatok létrehozása a következőképpen történik. Nyomd le a Control (ctrl) billentyűt és az egérrel a “Set to 5″ gombot kösd össze a MAfoo példánnyal a MainMenu.xib ablakban (ne visszafelé csináld!). A kapcsolatot jelképező vonal jól látható a képernyőn. Az objektum példány ikonjánál pedig egy legördülő menő lesz látható. Válaszd ki a “setTo5:”-t a listából.

20 Connect

A kapcsolat felállítása

Most már a gomb rendelkezik egy, a MAFoo objektumra mutató hivatkozással és el fogja küldeni neki a setTo5: üzenetet, amikor a gomb megnyomásra kerül.

Ezután a “Reset” gombot is összeköthetjük a MAFoo objektummal pontosan ugyanilyen módon.

Ahhoz, hogy létrehozzuk a kapcsolatot a MAFoo objektum és a szövegnező között, kezdjük a MAFoo objektumnál, nyomjuk le a Control billentyűt és kössük össze a szövegmező objektummal. Válasszuk ki a “textField”-et a menüből és ezzel kijelöltük a megfelelő kapcsolatot.

Mi a csuda történt most tulajdonképpen? Nos, néhány percen belül látni fogod, hogy anélkül hoztál létre egy programkódot, hogy egyetlen utasítást is leírtál volna!

Kódgenerálás

Először is győződj meg róla, hogy a MAFoo ki van választva a MainMenu.xib ablakban. Az Interface Builder File menüjéből válasszuk ki a Write Class Files-t. Az Interface Builder ekkor megkérdezi, hogy hova szeretnéd a programkódot elmenteni. Válaszd ki az alkalmazásunk projekt folderét és írasd felül a már létező MAFoo osztályt. Ellenőrizd, hogy a Language legördülő menüben az Objective C van kiválasztva és jelöld be, hogy “Create ‘.h’ file”.

23 Code

És most, ha visszamész az Xcode-hoz, megnézheted a legenerált fájlokat a projekt ablakon belül a Classes csoportban. Ha véletlenül a Resources, vagy másik csoportba kerültek volna, akkor egyszerűen fogd meg és húzd át a Classes csoportba őket. Kattints az Editor gombra az eszköztárban és válaszd ki a MAFoo.h fájlt.

23 Code

A legenerált programkódok látszanak az Xcode projektben

Emlékezzünk vissza a 3. fejezetre, amikor a függvényekről beszéltünk. Emlékszel a függvény fejlécére [11.1]? Ez egy figyelmeztetés volt a fordítóprogram számára, hogy mire kell számítania. Az imént két fájlt generáltunk, ezek közül az egyik a MAFoo.h, és ez egy fejléc (header): alapvető információkat tartalmaz az osztályunkról. Például a [3.5] sorban látható egy NSObject, és ez a sor azt mutatja, hogy az osztályunk az NSObject osztályból öröklődik.

//[3] 
/* MAFoo */ 
#import  <cocoa/cocoa.h>   // [3.2] 
@interface MAFoo : NSObject // [3.5] 
{
     IBOutlet id textField;	 // [3.7] 
}
 - (IBAction)reset:(id)sender; // [3.9]
 - (IBAction)setTo5:(id)sender; // [3.10] 
@end

Van itt egy outlet [3.7] is, ami a szövegmező objektumra mutat. Az id jelöli az objektumot. Az “IB” rövidítés pedig az Interface Builder-re utal, a programra, aminek segítségével ezt a kódot generáltuk.

IBAction [3.9, 3.10] ugyanazt jelenti, mint a void. Semmit nem kap vissza az objektum, amelyik küldi az üzenetet: a gombok ebben a programban nem kapnak semmilyen választ a MAFoo objektumtól az üzenetükre.

Láthatsz itt két Interface Builder akciót. Ez az osztályunk két metódusa. A metódusok majdnem olyanok, mint a már jól ismert függvénye, de van azért egy kis különbség közöttük. Erről majd később még lesz szó.

Korábbi alkalmazásainkban az #import utasítással találkoztunk a mostani [3.2] helyett. A korábbi a nem GUI alkalmazásokhoz kellett, ez pedig a grafikus interfészt használók számára szükséges.

Most pedig vizsgáljuk meg a másdik generált fájlt, a MAFoo.m-t. Ismét örülhetünk, hiszen potyára kaptunk egy programkódot.

//[4] 
#import "MAFoo.h" 
@implementation MAFoo - (IBAction)reset:(id)sender	// [4.5] 
{
} 
 - (IBAction)setTo5:(id)sender 
{ 
} 
@end

Mindenekelőtt vegyük észre, hogy a MAFoo.h header fájl be van importálva, tehát a fordítóprogram tudja, hogy mire számíthat. Két metódust láthatunk itt: reset: és setTo5:. Ezek az osztályunk metódusai. A függvényekhez hasonlóan itt is kapcsos zárójelek közé kell illeszteni a programkódot. Amikor megnyomjuk az egyik gombot, akkor az küld egy üzenetet a MAFoo objektumnak és megkéri az egyik metódus végrehajtását. Ennek a kódját az Interface Builder már elkészítette számunkra amikor összekötöttük a gombokat a MAFoo objektummal. Ezzel tehát nincs több dolgunk. Azonban életre kell keltenünk a két metódust, azaz meg kell írni az általuk tartalmazott függvények kódját. Jelen esetben ezek a metódusok semmi mást nem csinálnak, mint üzenetet küldenek a MAFoo objektumból a textField objektumnak, amint beírjuk az [5.7, 5.12] utasításokat.

//[5] 
#import "MAFoo.h" 
@implementation MAFoo 
- (IBAction)reset:(id)sender 
{
     [textField setIntValue:0];	// [5.7] 
} 
- (IBAction)setTo5:(id)sender 
{
     [textField setIntValue:5];	// [5.12] 
 } 
@end

Ahogy látható, küldünk egy üzenetet annak az objektumnak, amire a textField outlet hivatkozik. Mivel az Interface Builder-ben összekötöttük ezt az outletet az aktuális szövegmezővel, az üzenetünk a korrekt objektumhoz kerül. Az üzenet nem más, mint a metódus neve setIntValue: és egy egész szám. A setIntValue: metódus alkalmas arra, hogy megjelenítsen egy egész számot egy szövegmező objektumban. A következő fejezetben azt is eláruljuk, hogyan találtunk rá erre a metódusra.

Készen is vagyunk

Most már készek vagyunk arra, hogy lefordítsuk és futtassuk az alkalmazásunkat. Kattintsunk a Build and Go gombra az Xcode eszköztárában. Egy kis időre van szüksége az Xcode-nak ahhoz, hogy lefordítsa és betöltse a programot. Végül is az alkalmazás megjelenik a képernyőn és elkezdheted tesztelni.

23 Run

Az alkalmazásunk futás közben

Röviden összefoglalva: készítettél egy (nagyon kezdetleges) alkalmazást, és ehhez neked csupán két programsort kellett írnod!

eredeti oldal