jan 11 2011

Ismerkedés az Objective C runtime rendszerével

Mostanában elég gyakran túrom az Objective C runtime reference anyagot, és mondhatom hogy elég érdekes függvények vannak benne. :) Ha valaki igazán meg akarja érteni az Objective C belső működését, akkor érdemes alaposan áttanulmányozni a dokumentáció ezen részét.

A runtime egy shared libraryban található, ami minden Cocoa vagy iOS alkalmazáshoz hozzá van linkelve. Mire is lesz jó ez nekünk?

Ha kíváncsi vagy, hogyan működik a nyelv, hogy az egyes típusok (Class, id, SEL, IMP, Method, stb.) pontosan milyen adatszerkezeteket takarnak, vagy ha nem vagy megelégedve a Foundation* frameworkök által nyújtott introspection és reflection lehetőségekkel, akkor a runtime library az, amire szükséged van. Lényeges, hogy a runtime library C nyelven íródott, vagyis ha szeretnéd használni, akkor szükség lesz egy elfogadható C tudásra, és nyugodtan el lehet felejteni az Objective C nyelv sajátosságait. :) A runtime valójában egy elég nagy C adatszerkezet és C függvény gyűjtemény, amely a következő feladatokhoz ad eszközöket:

  • Classok vizsgálata, megváltoztatása, létrehozása futásidőben
  • Instance-ok vizsgálata, megváltoztatása futásidőben
  • Instance változók vizsgálata futásidőben
  • Az üzenetküldés low-level funkciói itt vannak
  • Metódusok vizsgálata, megváltoztatása futásidőben
  • Selectorok vizsgálata futásidőben
  • Protocol-ok vizsgálata futásidőben
  • Property-k vizsgálata futásidőben

A későbbiekben szeretnék részletesebben is írni ezekről a dolgokról, most viszont nézzünk meg egy egyszerű kis példát ízelítőként a runtime függvények erejéről. Amikor egy Objective C program elindul, a runtime rendszer beregisztrálja az összes Class-t, hogy azok felhasználhatók legyenek példányok létrehozásához.

Képzeljük el ezt úgy, hogy a runtime vezet egy listát a felhasználható Classokról (merthogy tényleg ez a helyzet). Hát, tegyük fel, hogy én nagyon kíváncsi vagyok erre a listára, és szeretnék egy olyan programot írni, ami kilistázza nekem sz összes beregisztrált Class-t. Hogy ne legyen olyan egyszerű a dolog, szeretném ha a kiírt lista egyben egy öröklési hierarchia is lenne, vagyis úgy listázzuk ki a classokat, hogy legfelül legyenek az ősosztályok, és alattuk pedig (valamilyen karakterrel jelölve hogy leszármazott osztály) beljebb kiírva a leszármazottaik, faszerkezetben. Lássuk, de előre szólok, hosszú lesz :) Continue reading


jan 4 2011

Primitív adattípusok

Kezdjük talán azzal, mit is jelent az hogy primitív adattípus. Alapvetően az alábbi két koncepció egyikét szokta jelenteni:

  • a “basic” típusok azok, amelyeket a programozási nyelv biztosít alapvető építőelemként
  • a beépített típusok azok, amelyekhez a programozási nyelv beépített támogatást biztosít

A legtöbb nyelvben a basic típusok egyben beépített típusok is, és általában nem engedélyezett a programok számára ezen primitív típusok képességeinek vagy viselkedésének megváltoztatása. Természetesen ez alól vannak kivételek, és léteznek olyan nyelvek (pl. Smalltalk), amelyek lehetővé teszik a primitív típusok kiterjesztését, és lehetséges bennük pl. új műveleteket hozzájuk adni, vagy felülbírálni a beépített műveletek jelentését.

A primitív típusok felhasználhatók komplexebb típusok létrehozására is. Az olyan típusokat amelyek primitív típusokból épülnek fel, kompozit típusoknak nevezzük. Sok nyelvben vannak beépített kompozit típusok is (pl. a struct), de arról megoszlanak a vélemények hogy ezeket is lehet-e primitívnek nevezni. Az én értelmezésem szerint a kompozit típusok nem primitívek. :)

Ennyi bevezető után lássuk milyen primitív típusokat biztosít az Objective C nyelv: int, float, double, char, void. Nem túl sok :)

Azonban hogy ne legyen ennyire egyszerű, léteznek úgynevezett típusminősítő kulcsszavak, amelyekkel megváltoztatható / beállítható az adott típus konkrét viselkedése. (Hogy pontosan milyen adatot képes eltárolni) A típusminősítő kulcsszavak a következők: signed, unsigned, short, long, long long

Nézzük meg az egyes típusokat közelebbről. Continue reading