Az iphone fejlesztés alapjai I. előadás A ponte.hu Kft. 2001 óta a piacon Web iphone, Android, Nokia és Windows mobile fejlesztések Újszerű megoldások és technológiák keresése A kurzus menete 3x45+2x45 perc Elméleti háttér és programozási alapok Elméleti órák Teszt 1x45 perc Az elméleti anyagból, a verseny a laborhelyekért megy Gyakorlat 4x3x45 perc, és egy kiegészítő bemutató előadás Közösen fogunk programozni, több témakört átívelve
A kurzus felépítése Elmélet Gyakorlat Nyelvi elemek Eszközök Szemlélet API A mai előadás témái I. Áttekintés Az iphone története Az iphone fejlesztés eszközei és menete II. Az Objective-C nyelv alapjai Objektum orientáltság III. Memória kezelés IV. Nézzünk meg egy példát I. Áttekintés
Az iphone története 2007. Első iphone kiadása Nagyon korlátozott: 2G, nincs alkalmazás telepítés, nincs GPS, nincs multitask, de forradalmian új felhasználói felület. 2008. iphone 3G Nagyon sok fájó pontot javít, megjelenik az AppStore 2009. iphone 3GS Ráncfelvarrás, nagyobb processzor teljesítmény, digitális iránytű (Augmented Reality), később multitask 2010. ipad, mad iphone 4 Nagy felbontású kijelző, giroszkóp Miért forradalmi? Nincs külső telepítés Korlátolt multitask Szeparált fájlrendszer Ellenőrzés AppStore Korlátozott funkciók Minimális testreszabás Minimális fragmentáció Megfelelő teljesítmény Felhasználói élmény Multitouch Egyetlen gomb Animált felületek Kötött készülékek Egyszerű kezelés Az iphone számokban Több mint 120 millió eladott ios készülék Több mint 250 000 alkalmazás Több mint 10 000 000 000 letöltés Tulajdonosok 50%-a már vásárolt alkalmazást
Miért az Apple a minta? Mobile készülékek 2010 I. félév Nokia, Samsung, LG 66% Profit megoszlás 2010 I. félév Others 29% Nokia, Samsung, LG 32% Apple 3% Others 31% Apple 39% Forrás: Fortune Az ios platform Támogatott eszközök: iphone 2G, 3G, 3GS, 4 ipod touch 1.-4. generáció ipad Minimális fragmentáció iphone SDK a fejlesztői környezet (csak Mac) Natív alkalmazások Objective-C nyelven A fejlesztés eszközei Xcode IDE A központ Debugger és Profiler alkalmazások Interface Builder Felületek építése Nem kötelező, de hasznos iphone Simulator Nem emulátor Jó teljesítmény Nem teljes
A fejlesztés menete Koncepció Fejlesztés Tesztelés Specifikáció Kódolás Szimulátor Arculat Felület építés Készülék II. Objective-C A nyelv kialakulása 1980-as évek elején a Stepstone cég alakította ki a Smalltalk alapján 1988-ban a NeXT licencelte a technológiát a NeXTstep rendszere alapjaként, amely később a Mac OS X alapja lett A C nyelv objektum orientált kiegészítéseként született, de nem azt az irányt követi, mint a C++ (Simula) C++: obj->method(argument); Objective-C: [obj method: argument];
Classname.h Osztályok @interface classname : superclassname { // instance variables +classmethod1; +(return_type)classmethod2; +(return_type)classmethod3:(param1_type)param1_varname; -(return_type)instancemethod1:(param1_type)param1_varname :(param2_type) param2_varname; -(return_type)instancemethod2withparameter:(param1_type)param1_varname andotherparameter:(param2_type)param2_varname; Classname.m @implementation classname +classmethod { // implementation -instancemethod { // implementation Mezők elérése @interface MyFirstClass : NSObject { @public int publicnumber; @protected // Protected is the default char protectedletter; @private bool privatebool; @implementation MyFirstClass - mymethod { publicnumber = 3; protectedletter = 'Q'; privatebool = NO; @implementation OtherClass - (id)mymethod2 { MySecondClass *other; other = [[MyFirstClass alloc] init]; other- >publicnumber = 42; Metódusok elérése A metódus hívások üzenet küldésekként vannak kezelve, csak futási idejű a hozzárendelés, ezért nincs igazi privát metódus @interface MyClass { // My Instance Variables - (void)mypublicmethod; @interface MyClass() - (void)myprivatemethod; @implementation MyClass - (void)mypublicmethod { // Implementation goes here - (void)myprivatemethod { // Implementation goes here
Konstruktorok Az objektumokat mindig mutatókkal érjük el MyObject *o = [[MyObject alloc] init]; Alap konstruktor felül definiálása -(id) init { if ( self = [super init] ) { // perform initialization of object here return self; Konstruktor paraméterekkel -(id) initwithx: (int)xcord y:(int)ycord { if ( self = [super init] ) { width=xcord; height=ycord; return self; Öröklődés Egyszeres öröklődés @interface Car : Vehicle { Többszörös öröklődés helyett protokollok @protocol Motoros -(int)geturtartalom; Protokoll megvalósítás @interface Car : Vehicle <Motoros>{ III. Memóriakezelés
Nincs Garbage Collection GC Nem kell foglalkozni a memória felszabadítással De gyakorlatilag nem is lehet Kevesebb hibalehetőség, de kevésbé hatékony Kézi kezelés Hibalehetőségek: Memory leak és Bad Access Kiszámítható teljesítmény, de munkás Statikus és dinamikus elemző eszközök Retain...Release -(void)dosomething{! SomeObj* someobject=[[someobj alloc] init];!.!.! do something with the object!.!.! [someobject release]; alloc refaincount=1 retain refaincount++ dosomething release refaincount-- No -(void)usesomething:(nsstring*)someobject{! [someobject retain];! myobject=someobject; retaincount==0? -(void)dontneedanymore{! [myobject release];! myobject=nil; Yes dealloc Property Hogy néz ki egy egyszerű setter? -(void) settext:(nsstring *)textvalue { if (textvalue!= text) { [textvalue retain]; [text release]; text = textvalue; SomeObject.h Mindezeket megcsináltathatjuk a fordítóval is! #import <Foundation/Foundation.h> SomeObject.m #import "SomeObject.h" @interface SomeObject : NSObject {! NSString* text; @property (nonatomic,retain) NSString* text; @implementation SomeObject @synthesize text;
Property Hogyan használjuk más osztályokban?! SomeObject* someobject=[[someobject alloc] init];! someobject.text=@"hello";! NSString* localtext=someobject.text; További lehetőségek @property (nonatomic,retain) NSString* text; nincs nonatomic: alaptípus (pl: int) readonly: csak getter készül assign: nincs retain/release, szimpla értékadás copy: új példány készítése Autorelease Pool Az eddigi modell jól működik tagváltozók esetében. Viszont lokálisan felhasznált változók, vagy főleg API hívások lokálisan használt eredményei esetén ez nagyon macerás megoldás (mindenre release) Megoldás: Autorelease Pool Az autoreleaselt objektumoknál nem kell foglalkozni a felszabadítással, de csak egy cikluson belül érvényes! NSString* test=@"test"; NSLog(test); test=[nsstring stringwithformat:@"test: %d",2]; NSLog(test);! SomeObject* someobject=[[someobject alloc] init];! [someobject autorelease]; Autorelease Pool működése Start NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Do Something [pool drain]; End
Memória kezelési szabályok Főszabály Azokat az objektumokat kell release, vagy autoreleaseelni, amelyek a birtokunkban vannak Egy objektum akkor kerülhet a birtokunkba, ha a metódus neve, amivel létrehoztuk tartalmazza az alloc, new vagy copy szavakat (pl. alloc, newobject, mutablecopy.), vagy retain-t hívtunk az objektumra. Az objektumot tulajdonjogát, akkor engedjük el, ha release, vagy autorelease-t (releaseld valamikor a jövőben) hívunk rajta. Build and Analyze Bár a fenti szabályok nem követhetetlenek, nagyon könnyen idézhetünk elő nehezen megtalálható hibákat. Ha kimaradt egy release, akkor memory leaket okoztunk, aminek nincs közvetlen hatása, csak egyszer elfogy a memória. Ha egyel több release van, vagy utána akarunk hozzáférni, akkor kapunk egy BAD_ACCESS hibaüzenetet, amit szintén nehéz megtalálni, mert ki tudja miért volt már a téves felszabadítás. Statikus analizátor: Xcode Build/Build and Analyze C típusú memóriakezelés Az Objective-C a C kiterjesztése, minden, ami működik C-ben, az működik itt is. Ez sokszor nem a legjobb megoldás, mert nem objektum orientált és még könnyebb hibázni, könnyen okozhatunk buffer overflow-t. Viszont adott esetben nagyon gyors és helytakarékos! typedef struct{!! int x;!! int y;! Point;!! Point* points;! points=malloc(100*sizeof(point));! points[0].x=0;! points[0].y=0;! points[99].x=0;! points[99].y=0;! free(points);
III. Gyakorlat Mit fogunk csinálni? Egyszerű OOP feladat Van egy ős protokoll (Shape), amelynek az a specialitása, hogy lekérdezhető a területe Ezt megvalósítja két osztály Square, Circle, amelyeket oldalhosszukkal és sugarukkal inicializálunk Van egy Calculator osztály, amely egy statikus metódusban készít egy Circle-t és egy Square-t, majd a területüket összeadja Az Xcode megnyitása
Új projekt létrehozása Az Xcode képernyője Új fájl hozzáadása
Adjunk fájlokat a grouphoz Shape.h #import <UIKit/UIKit.h> @protocol Shape -(double)getarea; Square.h #import <Foundation/Foundation.h> #import "Shape.h" @interface Square : NSObject <Shape>{! double sidelength; -(id)initwithside:(double)length;
Square.m #import "Square.h" @implementation Square -(id)initwithside:(double)length{! self = [super init]; if ( self ) {!! sidelength=length;! return self; -(double)getarea{! return sidelength*sidelength; Circle.h #import <Foundation/Foundation.h> #import "Shape.h" @interface Circle : NSObject <Shape>{! double circleradius; -(id)initwithradius:(double)radius; Circle.m #import "Circle.h" @implementation Circle -(id)initwithradius:(double)radius{! self = [super init]; if ( self ) {!! circleradius=radius;! return self; -(double)getarea{! return circleradius*circleradius*m_pi;
Calculator.h #import <Foundation/Foundation.h> @interface Calculator : NSObject { +(double)calculate; Calculator.m #import "Calculator.h" #import "Circle.h" #import "Square.h" @implementation Calculator +(double)calculate{! Circle* circle=[[circle alloc] initwithradius:2.0];! Square* square=[[square alloc] initwithside:2.0];!! id<shape> shapes[2]={circle,square;! double sum=0;! for (int i=0;i<2;i++){!! sum+=[shapes[i] getarea];!! NSLog(@"i: %d %f",i,[shapes[i] getarea]);!! [circle release];! [square release];! return sum; AppDelegate - (BOOL)application:(UIApplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { // Override point for customization after application launch.! double result=[calculator calculate];! NSString* resultstring=[nsstring stringwithformat:@"result: %f",result];! UIAlertView *alert = [[UIAlertView alloc] initwithtitle:nil message:resultstring!!!!!! delegate:self cancelbuttontitle:@"ok" otherbuttontitles:nil];! [alert show];! [alert release];! [window makekeyandvisible]; return YES;
Az eredmény Köszönöm a figyelmet! Sallai Péter peter.sallai@ponte.hu