Letölthető példaprogramok
Kattints a linkre a példaprogramok letöltéséhez!
Hello, World
Egyszerű c hello-world program, ami Objective-C ben is lefordul és működik.
hello.m
A @"Hello, World!" egy Objective-C sztring objektumot hoz létre (automatikusan), ami a program végén szabadul fel.
A <Foundation/Foundation.h> tartalmazza a szükséges osztálydefiniókat, ezért importálni kell.
hellognustep.m
Boolean típus
Érdekesség: true és false helyett YES és NO használható.
boolean.m
Osztályok, Kategóriák
Fejléc fájl - az osztály adattagjait és metódusdeklarációit tartalmazza.
Complex.h
Az osztály metódusainak megvalósítása megvalósítása .m kiterjesztésű fájlokba kerül.
Complex.m
Az osztályokat kibővíthetjük kategóriákkal, ezek további műveleteket rendelnek az adott osztályhoz.
ComplexOperations.h
Posing, Protokoll megvalósítás
Posing segítségével lecserléhetjük az osztály belső műveleteit, származtatás nélkül.
posing.m
Őröklődés
Az alábbiakban egy betegeket ellátó intézmény működését szemléltető példaprogramot láthatunk. A betegek különböző betegségekkel jelentkeznek, majd a program betegségek szerint beosztja őket a megfelelő orvosokhoz, ahol azok ellátásban részesülnek.
A projekt neve: MedicalCenter
A projekt struktúrája:
MedicalCenter
|
|__lib
| |
| |__entities
| | |
| | |__Human.h, Human.m
| | |__Patient.h, Patient.m
| | |__Doctor.h, Doctor.m
| | |__Disease.h, Disease.m
| | |__Printing.h
| |
| |__utils
| |
| |__MCManager.h, MCManager.m
|
|__res
| |
| |__doctors.csv
| |__diseases.csv
| |__patients.csv
|
|_main.m
Entitások
Human.h:
Human.m:
Patient.h:
Patient.m:
Doctor.h:
Doctor.m:
Disease.h:
Disease.m:
Printing.h:
A manager osztály
MCManager.h
A főprogram
main.m
A program fordítása Linux rendszeren, GCC fordítóval a következőképpen lehetséges:
Kivételkezelés
kivetel.m
Szálkezelés, lockolás
thread.m
Szálak - Paraméterátadás, időzítés
timer.m
Taszkok
tasks.m
RunLoop
runloop.m
Minimalista GNUStep/AppKit desktop alkalmazás
Egy desktop alkalmazás elkészítéséhez először szükség van egy NSApplication példányra, mely az egész alkalmazást hivatott reprezentálni. Két lehetőség van az alkalmazások testreszabására :
- Az NSApplication specializálása (származtatása).
- Delegált osztály hozzárendelése.
A Delegált lényege hogy az NSApplication bizonyos eseményeinek kezelésére biztosítson szabványos felületet. Bővebb információkért :
- Mac OS X Developer Library - NSApplication class reference
- Mac OS X Developer Library - NSApplicationDelegate protocol reference
- Az alkalmazás indulása előtt létre fogja hozni az alkalmazásban használatos GUI elemeket
- Eljárást biztosít egy egyszerű "alert" panel kijelzésére
- Mechanizmust biztosít a használt ablak láthatóvá tételére
Az applicationWillFinishLaunching: eljárást az alkalmazás még az indulása előtt futtani fogja, ezért kitűnő alkalom a GUI komponensek inicializációjára. Egy másik inicializációs pont lehetne például az AppDelegate objektum saját init eljárása.
Néhány megjegyzés a fenti kódhoz :
- A GNUStep/Cocoa környezet a koordinátasík (0,0) koordinátájának a képernyő bal alsó sarkát felelteti meg. Szemben pl.: C#-ban szokásos bal felső sarokkal.
- A kód Windows XP rendszeren lett tesztelve. Annak ellenére hogy a styleMask értékénél nem lett megadva az ablak kikapcsolhatósága, meg fog jelenni a szokásos [X] azonban nem fog működni. (Helyette sípol ha megnyomják :D)
- A kód egy nagyon egyszerű ablakot állít össze, azonban ennél jóval bonyolultabb összetételekre is van lehetőség. Valósi fejlesztések esetében az ilyen felületek elkészítését valamilyen IDE/Tool segítségével végezzük, mint pl.: A Mac OS X pletformon használható XCode.
- Egy jó átfogo képet biztosít az AppKit összetételéről a következő webhely : Mac OS X Developer Library - Applicatin Kit Framework Reference . Amennyiben GNUStep környezetben fejlesztünk tartsuk szem előtt hogy nem minden komopnens áll rendelkezésünkre a Cocoa eszköztárából. A GNUStep megfelelő dokumentációja megtalálható a http://www.gnustep.org/resources/documentation/Developer/Gui/Reference/ címen, azonban nagymértékben hiányos (hiányoznak a magyarázatok nagyon sok helyen).
- A GUI komponensek esetében gyakran találkozunk a target-action sémával. Ennek lényege hogy megadunk egy "target" objektumot majd, egy egy paraméteres metódust (action) az objektumnak. Amikor interakció történik akkor a következő sornak megfelelő program hajtódik végre : [target action: self];
A kódot GNUMakefile segítségével fordíthatjuk :
Tologatós jaték
A továbbiakban a klasszikus tologatós játék egy lehetséges implementációja
található. A játék lényege, hogy egy kép összekevert képrészleteit megfelelően
elmozgatva, megkapjuk az eredeti képet. A felhasználónak a program indításakor
lehetősége van képet választani és meghatározni, hogy egy sor és oszlop hány darabra legyen
felosztva.
Két osztályt hozunk létre: a Tilitoli és az AppControl nevűt.
Most pedig az egyes metódusok implementálása:
Ezután elkészíthető az AppControl nevű osztály, melyben csak egyetlen metódust implementálunk, méghozzá az NSApplicationDelegate protokolból. A neve applicationDidFinishLaunching. Erre akkor lesz szükség, amikor a program belépési pontjában delegáltként beállítjuk az AppControl osztály egy példányát. Ennek köszönhetően a delegált értesül arról, amikor az alkalmazás elindult és még mielőtt az bármilyen eseményt fogadna lefut az applicationDidFinishLaunching metódus.
A fordításhoz a következő GNUmakefile használható:
A fordítás után a Tilitoli.app mappába lépve a parancssorból a futtatható az alkalmazás:
A fenti módon indított alkalmazás 4x4-es táblát eredményez, amin a virag.jpg kép lesz megjelenitve.
Minimalista tanulmányi rendszer
A következőekben egy egyszerű tanulmányi rendszer implementációjáról olvashatsz. Ebben a következő osztályokat implementálom:
- Student: tanuló
- Teacher: tanár
- EtrHuman: A személyek tanulmányi rendszer beli reprezentációja, a tanuló és a tanár őse.
- Course: kurzus
- ETR: Az előzőek menedzselését végzi.
A tanulók és tanárok ősosztálya két tulajdonságot, a nevet és az eha kódot tartalmazza.
A diák képes kurzusok felvételére, és a felvett kurzusok adatainak kiírására.
A tanárok és kurzusok között egy-egy kapcsolat áll fenn.
A kurzus számontartja az őt felvevő diákokat, és a hozzárendelt tanárt.
Az ETR végzi a diákok, tanárok és kurzusok listába gyűjtését, felületet biztosít a tantárgyak felvételére és a diákok órarendjének kiírására.
Őröklődés, alakzatok, láncolt lista
A következő példaprogramban alakzatok osztályait származtatjuk egymásból. Ezek téglalap, négyzet, kör és Shape az ősosztály. Objektumokat hozunk létre, majd ezeket szimpla láncolt listába füzzük és meghívjuk a print metódust, ami kiirja az alakzat nevét. A programban van példa dinamikuskötésre (id), methódusok (szelektorok) felüldefiniálására, illetve manuális memória kezelésre (retain, release, dealloc). A programban látható, hogy protokol (printable) segítségével hogyan lehet kőtelezővé tenni metódusok (print) implementálását. A program tartalmaz egy láncolt lista egy lehetséges implementációját is.
A weblapról hiányzik a felhasználói felület, amivel az adatokat lehet rögzíteni, illetve a főprogram mivel ezek sok érdekességet már nem tartalmaznak. A letölthető programok között ezek is megtalálhatóak.
MonkeyRunner - Alap iOS játék cocos 2D keretrendszer segítségével
A játék iOS platformra készült, nyílt forráskódú cocos 2D keretrendszer segítségével, amely a 2D világ szimulálását segíti.
cocos 2d weboldalaA játékban egy katapult segítségével kell eltalálni banánnal egy távolban lévő majmot.
MonkeyWorldLayer.h - a világot, a katapultot, töltényeket, majmot valamint a textúrákat, kameramozgást és egyéb animációkat leíró fájl header fájlja
MonkeyWorldLayer.mm - implementációs rész
MyContactListener.h - collision detection, vagyis az ütközést detektáló osztály header része
MyContactListener.cpp - implementációs rész
Egyszerű böngésző a WebKit keretrendszer használatával OSX platformra.
A navbar-ban megadott címet letölti, az eseményeket naplózza és előre-hátra lép a megtekintett oldalak közt.
SBAppDelegate.h
#import#import @interface SBAppDelegate : NSObject { int resourceCount; } @property (assign) IBOutlet NSWindow *window; @property (assign) IBOutlet NSTextField *navbar; @property (assign) IBOutlet WebView *webview; @property (strong) IBOutlet NSButton *backButton; @property (strong) IBOutlet NSButton *forwardButton; @property (strong) IBOutlet NSProgressIndicator *progress; - (IBAction)go:(id)sender; @end
SBAppDelegate.mm
#import "SBAppDelegate.h"
@implementation SBAppDelegate
@synthesize backButton;
@synthesize forwardButton;
@synthesize progress;
@synthesize window;
@synthesize navbar;
@synthesize webview;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[navbar setStringValue:@"http://nyelvek.inf.elte.hu/leirasok/Objective_C/"];
[self go: navbar];
}
- (IBAction)go:(id)sender {
WebFrame *mainFrame = [webview mainFrame];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[navbar stringValue]]];
[mainFrame loadRequest: request];
}
/**
Frame Load Delegate
**/
/*!
Keretletöltés kezdete.
Most a navbar-ba beírjuk a frissen töltött címet
A bitkolbászt elindítjuk
*/
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame {
NSLog(@"Keret letöltés indul: %@", [frame name]);
if(![frame parentFrame]) {
NSString *url = [[[[frame provisionalDataSource] request] URL] absoluteString];
[navbar setStringValue:url];
[progress startAnimation:frame];
}
}
/*!
Keret címe megérkezett
*/
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
{
NSLog(@"Keret cím megérkezett: %@ cím: %@", [frame name], title);
// Report feedback only for the main frame.
if (frame == [sender mainFrame]){
[[sender window] setTitle:title];
}
}
/*!
Keret letöltés vége
History előre-hátra engedélyezése és tiltása
A bitkolbászt leállítjuk
*/
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
NSLog(@"Keret letöltés kész: %@", [frame name]);
if (frame == [sender mainFrame]){
[backButton setEnabled:[sender canGoBack]];
[forwardButton setEnabled:[sender canGoForward]];
[progress stopAnimation:frame];
}
}
/*!
A szerver átirányított
*/
- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
{
NSLog(@"Szerveroldali átirányítás: %@", [frame name]);
}
/*!
Az ideiglenes letöltés sikertelem
*/
- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
{
NSLog(@"Ideiglenes letöltés sikertelen: %@ hiba: %@", [frame name], [error localizedDescription]);
}
/*!
A véglegesített letöltés sikertelem
*/
- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
{
NSLog(@"Végleges letöltés sikertelen: %@ hiba: %@", [frame name], [error localizedDescription]);
}
/*!
Adat érkezett, letöltés véglegesíthető
*/
- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
{
NSLog(@"Keret letöltés véglegesítve: %@", [frame name]);
}
/*!
Keret scroll pozíciója megváltozott
*/
- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
{
NSLog(@"Keret scroll pozíciója megváltozott: %@", [frame name]);
}
/*!
A keret záródik
*/
- (void)webView:(WebView *)sender willCloseFrame:(WebFrame *)frame
{
NSLog(@"A keret záródik: %@", [frame name]);
}
/**
Resource Load Delegate
**/
/*!
Új erőforrás-azonosító. Számozzuk, a következő üzenetekben a sorszámmal hivatkozunk
*/
- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource {
id identifier = [NSNumber numberWithInt:resourceCount++];
NSLog(@"Új erőforrás sorszám: %@, %@", [request URL], identifier);
return identifier;
}
/*!
Indul az erőforrás letöltése
*/
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
NSLog(@"Erőforrás letöltése indul: %@", identifier);
return request;
}
/*!
Indul az erőforrás letöltése
*/
- (void)webView:(WebView *)sender resource:(id)identifier didReceiveResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
{
NSLog(@"Adat jött erőforráshoz: %@", identifier);
}
/*!
Megjött az erőforrás hossza
*/
- (void)webView:(WebView *)sender resource:(id)identifier didReceiveContentLength:(int)length fromDataSource:(WebDataSource *)dataSource
{
NSLog(@"Megjött az erőforrás hossza: %@: %d", identifier, length);
}
/*!
Erőforrás kész
*/
- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
{
NSLog(@"Erőforrás kész: %@", identifier);
}
/*!
Erőforrás sikertelen
*/
- (void)webView:(WebView *)sender resource:(id)identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
{
NSLog(@"Erőforrás sikertelen: %@, hiba: %@", identifier, [error localizedDescription]);
}
@end
Alapok a GNUStep használatával Linuxra
Két komplex szám (a,b) inicializálása, majd (a+b)*b kiszámítása
main.m
#import "MyComplexDemo.h" #import#import int main( int argc, const char *argv[] ) { NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init]; Writer* w = [[Writer alloc] init]; MyComplexDemo* demo = [[MyComplexDemo alloc] init]; [[w class] WriteString : @"MyComplexDemo : Initialized : Done \n"]; [demo WriteWelcome]; [[w class] WriteString : @"MyComplexDemo : WriteWelcome : Done \n"]; [demo SetupDummyComplexes]; [[w class] WriteString : @"MyComplexDemo : A Initialized : Real : \n"]; [[w class] WriteDouble : [demo GetReal_A]]; [[w class] WriteString : @"MyComplexDemo : A Initialized : Imaginary : \n"]; [[w class] WriteDouble : [demo GetImaginary_A]]; [[w class] WriteString : @"MyComplexDemo : B Initialized : Real \n"]; [[w class] WriteDouble : [demo GetReal_B]]; [[w class] WriteString : @"MyComplexDemo : B Initialized : Imaginary \n"]; [[w class] WriteDouble : [demo GetImaginary_B]]; [[w class] WriteString : @"MyComplexDemo : A + B : Real & Imaginary \n"]; [demo DemoOperationAdd]; [[w class] WriteDouble : [demo GetReal_A]]; [[w class] WriteDouble : [demo GetImaginary_A]]; [[w class] WriteString : @"MyComplexDemo : (A + B)*B : Real & Imaginary \n"];0 [demo DemoOperationMultiply]; [[w class] WriteDouble : [demo GetReal_A]]; [[w class] WriteDouble : [demo GetImaginary_A]]; [myPool drain]; return 0; }
MyComplexDemo.h
#import#import "MyComplex.h" #import "Writer.h" #import "Reader.h" @interface MyComplexDemo : NSObject { MyComplex* dummyA; MyComplex* dummyB; Writer* demoWriter; Reader* demoReader; } - (id) init; - (void) WriteWelcome; - (void) SetupDummyComplexes; - (void) SetupDummy_A; - (void) SetupDummy_B; - (double) GetReal_A; - (double) GetReal_B; - (double) GetImaginary_A; - (double) GetImaginary_B; - (void) DemoOperationAdd; - (void) DemoOperationMultiply; @end
MyComplexDemo.m
#import "MyComplexDemo.h" #import@implementation MyComplexDemo - (id) init { self = [super init]; if (!self) { NSLog(@"Super Class Initialization : Failed \n"); return nil; } else { dummyA = [[MyComplex alloc] init]; dummyB = [[MyComplex alloc] init]; demoWriter = [[Writer alloc] init]; demoReader = [[Reader alloc] init]; NSLog(@"Super Class Initialization : Done \n"); return self; } } - (void) WriteWelcome { [[demoWriter class] WriteString: @"Welcome to MyComplex Demo Application \n"]; [[demoWriter class] WriteString: @"This little app will demonstrate calculating with complex numbers \n"]; } - (void) SetupDummyComplexes { [self SetupDummy_A]; [self SetupDummy_B]; } - (void) SetupDummy_A { double tReal, tImaginary; [[demoWriter class] WriteString: @"Please enter complex A's Real:"]; tReal = [demoReader ReadDouble]; [[demoWriter class] WriteString: @"Please enter complex A's Imaginary:"]; tImaginary = [demoReader ReadDouble]; [dummyA SetReal : tReal]; [dummyA SetImaginary : tImaginary]; } - (void) SetupDummy_B { double tReal, tImaginary; demoReader = [[Reader alloc] init]; [[demoWriter class] WriteString: @"Please enter complex B's Real:"]; tReal = [demoReader ReadDouble]; [[demoWriter class] WriteString: @"Please enter complex B's Imaginary:"]; tImaginary = [demoReader ReadDouble]; [dummyB SetReal : tReal]; [dummyB SetImaginary : tImaginary]; } - (double) GetReal_A { return [dummyA GetReal]; } - (double) GetReal_B { return [dummyB GetReal]; } - (double) GetImaginary_A { return [dummyA GetImaginary]; } - (double) GetImaginary_B { return [dummyB GetImaginary]; } - (void) DemoOperationAdd { [dummyA Add: dummyB]; } - (void) DemoOperationMultiply { [dummyA Multiply: dummyB]; } @end
MyComplex.h
#import#import "IComparable.h" @interface MyComplex : NSObject { double real; double imaginary; } -(id)init; -(void) SetReal: (double)aReal; -(void) SetImaginary: (double)anImaginary; -(double) GetReal; -(double) GetImaginary; -(MyComplex*) Add: (MyComplex*)otherComplex; -(MyComplex*) Multiply: (MyComplex*)otherComplex; @end
MyComplex.m
#import "MyComplex.h"
@implementation MyComplex
-(id) init
{
self = [super init];
if (!self) return nil;
else
{
return self;
}
}
- (void) SetReal : (double)aReal
{
if (aReal != 0.0)
{
real = aReal;
}
}
- (void) SetImaginary : (double)anImaginary
{
if (anImaginary != 0.0)
{
imaginary = anImaginary;
}
}
- (double) GetReal
{
return real;
}
- (double) GetImaginary
{
return imaginary;
}
- (MyComplex*) Add : (MyComplex*)otherComplex
{
if (otherComplex != 0)
{
double oReal = [otherComplex GetReal];
double oImaginary = [otherComplex GetImaginary];
real += oReal;
imaginary += oImaginary;
}
return self;
}
- (MyComplex*) Multiply: (MyComplex*)otherComplex
{
if (otherComplex != 0)
{
double oReal = [otherComplex GetReal];
double oImaginary = [otherComplex GetImaginary];
real = (oReal*real) - (oImaginary*imaginary);
imaginary = (imaginary*oReal)+(real*oImaginary);
}
return self;
}
- (BOOL) Equals: (id) otherObject
{
if (real == [otherObject GetReal] && imaginary == [otherObject GetReal])
return true;
else
return false;
}
- (BOOL) GreaterThan: (id) otherObject
{
if (real >= [otherObject GetReal] && imaginary >= [otherObject GetReal])
return true;
else
return false;
}
@end
IComparable.h
@protocol IComparable -(BOOL)Equals:(id)otherObject; -(BOOL)GreaterThan:(id)otherObject; @end
Reader.h
#import#import @interface Reader : NSObject { } -(id)init; -(int) ReadInt; -(double) ReadDouble; -(float) ReadFloat; @end
Reader.m
#import "Reader.h"
@implementation Reader
-(id) init
{
self = [super init];
if (!self) return nil;
else
{
return self;
}
}
- (int) ReadInt
{
int tempInt;
scanf(" %d ", &tempInt);
return tempInt;
}
- (double) ReadDouble
{
double tempDouble;
scanf(" %lf", &tempDouble);
return tempDouble;
}
- (float) ReadFloat
{
float tempFloat;
scanf(" %f", &tempFloat);
return tempFloat;
}
@end
Writer.h
#import@interface Writer : NSObject { } -(id)init; +(void) WriteString : (NSConstantString*)aSource; +(void) WriteInt : (NSConstantString*)aMessage : (int)aSource; +(void) WriteDouble: (double)aSource; +(void) WriteFloat : (NSConstantString*)aMessage : (float)aSource; @end
Writer.m
#import "Writer.h"
@implementation Writer
-(id) init
{
self = [super init];
if (!self) return nil;
else
{
return self;
}
}
+ (void) WriteString : (NSConstantString*)aSource
{
NSLog(aSource);
}
+ (void) WriteInt : (NSConstantString*)aMessage : (int)aSource
{
NSLog(@"%d",aMessage, aSource);
}
+ (void) WriteDouble : (double)aSource
{
NSLog(@"%f", aSource);
}
+ (void) WriteFloat : (NSConstantString*)aMessage : (float)aSource
{
NSLog(aMessage, aSource);
}
@end
Képek letöltése párhuzamosan
A program lehetőséget biztosít képek letöltésére külön szálakban NSInvocationOperation segítségével. Megadható, hogy hány konkurens szál fusson egyszerre.
Szerző: Tóth Ã�dám (2013)
Használt fejlesztőkörnyezet: OS X 10.9, XCode 4.6.2
Példaprogram letöltéseSzámológép, GNUstep alkalmazások segítségével
A fentebb bemutatott eszközök mélyebb megismeréséhez most bemutatom, hogyan lehet ezek segítségével könnyen, gyorsan grafikus felülettel
rendelkező programot készíteni Objective-C nyelven Windows alatt.
Indítsuk el a ProjectCenter-t és válasszuk a Project->New lehetőséget. A „New Projectâ€� dialógusban válaszuk az Application projekt
típusnak, és válaszuk meg a helyét és a nevét, ami jelen esetben Calculator lesz.
Itt jegyezném meg, hogy elsőre elég zavaró lehet, hogy a GNUstep-es alkalmazások olyan módon jelennek meg, hogy külön ablakokban van minden része, és a menüje megint csak külön életet él. Ezt a NextStep-től örökölte és kis idő után meg lehet szokni de az első időkben eléggé oda kell figyelni.
Ha valamelyik ablak nem jelenne meg a Tools menüben tudjuk megjeleníteni őket.
Először válaszuk a Window-t, és húzuk a Gorm Document-be
Végre neki állhatunk a felhasználói felület kialakításának. A jól bevált drag&drop technikával a Palettes ablakból tegyük fel a MainWindow-onkra a kívánt elemek, majd állítsuk be a tulajdonságaikat, és elrendezésüket nekünk tetszően.
Valami hasonló eredmény elérése a cél:
Ezután össze kell kötni az osztály és a felület tulajdonságait. Először az outlets-eket kötjük a felületen lévő textbox-okkal, hogy futási időben hozzáférhessünk az értékéhez a változón keresztül. Ezt úgy tehetjük meg hogy a Gorm főablakában rákattintunk a CalculatorManager-re majd a jobb oldali Ctrl-t nyomva tartva drag&drop-oljuk a megfelelő textbox-ra. Ekkor kis magenta T jelenik meg a textbox-ban, és zöld S jelenik meg a CalculatorManager-en. Az inspector-ban pedig kiválaszthatjuk a megfelelő Outlets-et, és ezzel létrejön a kapcsolat.
Térjünk vissza a ProjectCenter alkalmazásba, és dupla klikkeljünk a Classes-re a főablak bal felső részén, és a felugró ablakban válaszuk a CalculatorManager.m fájlt, a header fájl automatikusan hozzáadódik a projekthez. Ezután, megjelenik a második oszlopban, és kiválasztva már szerkeszthetjük is a kódot.
A forráskód:
CalculatorManager.h
#include@interface CalculatorManager : NSObject { id history; id result; double lastKnownValue; NSString *operand; BOOL isInEqualMod; } - (void) add: (id)sender; - (void) division: (id)sender; - (void) eight: (id)sender; - (void) equal: (id)sender; - (void) erase: (id)sender; - (void) five: (id)sender; - (void) four: (id)sender; - (void) multiply: (id)sender; - (void) dot: (id)sender; - (void) nine: (id)sender; - (void) one: (id)sender; - (void) seven: (id)sender; - (void) six: (id)sender; - (void) subtract: (id)sender; - (void) three: (id)sender; - (void) two: (id)sender; - (void) zero: (id)sender; @end
CalculatorManager.m
#include#include "CalculatorManager.h" @implementation CalculatorManager - (BOOL)doesStringContainDecimal:(NSString*) string { NSString *searchForDecimal = @"."; NSRange range = [[result stringValue] rangeOfString:searchForDecimal]; if (range.location != NSNotFound) return YES; return NO; } - (void)calculate { double currentValue = [result doubleValue]; if (lastKnownValue != 0) { if ([operand isEqualToString:@"+"]) lastKnownValue += currentValue; else if ([operand isEqualToString:@"-"]) lastKnownValue -= currentValue; else if ([operand isEqualToString:@"*"]) lastKnownValue *= currentValue; else if ([operand isEqualToString:@"/"]) { if (currentValue == 0) [result setStringValue: @"ERR: Devide by Zero"]; else lastKnownValue /= currentValue; } } else lastKnownValue = currentValue; } - (void) add: (id)sender { [self calculate]; operand = @"+"; [history setStringValue: [[history stringValue] stringByAppendingFormat:[result stringValue]]]; [history setStringValue: [[history stringValue] stringByAppendingFormat:@" + "]]; [result setStringValue: @""]; } - (void) division: (id)sender { [self calculate]; operand = @"/"; [history setStringValue: [[history stringValue] stringByAppendingFormat:[result stringValue]]]; [history setStringValue: [[history stringValue] stringByAppendingFormat:@" / "]]; [result setStringValue: @""]; } - (void) eight: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"8"]]; } - (void) equal: (id)sender { [self calculate]; [history setStringValue: [[history stringValue] stringByAppendingFormat:[result stringValue]]]; [history setStringValue: [[history stringValue] stringByAppendingFormat:@" = "]]; [result setStringValue: @""]; [result setStringValue: [NSString stringWithFormat:@"%g",lastKnownValue]]; operand = @""; } - (void) erase: (id)sender { [result setStringValue: @""]; [history setStringValue: @""]; operand = @""; lastKnownValue = 0; } - (void) five: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"5"]]; } - (void) four: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"4"]]; } - (void) multiply: (id)sender { [self calculate]; operand = @"*"; [history setStringValue: [[history stringValue] stringByAppendingFormat:[result stringValue]]]; [history setStringValue: [[history stringValue] stringByAppendingFormat:@" * "]]; [result setStringValue: @""]; } - (void) dot: (id)sender { if ([self doesStringContainDecimal:[result stringValue]] == NO && [result stringValue] != @"") [result setStringValue: [[result stringValue] stringByAppendingFormat:@"."]]; } - (void) nine: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"9"]]; } - (void) one: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"1"]]; } - (void) seven: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"7"]]; } - (void) six: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"6"]]; } - (void) subtract: (id)sender { [self calculate]; operand = @"-"; [history setStringValue: [[history stringValue] stringByAppendingFormat:[result stringValue]]]; [history setStringValue: [[history stringValue] stringByAppendingFormat:@" - "]]; [result setStringValue: @""]; } - (void) three: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"3"]]; } - (void) two: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"2"]]; } - (void) zero: (id)sender { [result setStringValue: [[result stringValue] stringByAppendingFormat:@"0"]]; } @end
Szerző: Kur Barnabás (2013)
Használt fejlesztőkörnyezet: Windows 8 Enterprise x64, GNUStep 0.30
Logikai feladvany
A feladat:
Adott 4 ember, aki át szeretne jutni a szakadék túloldalára egy hídon keresztül. Mivel korom sötét van mindenképpen lámpát kell használniuk a hídon történő áthaladáshoz. Lámpa csak egy van, ezért párban haladnak át a hídon és egy mindig visszahozza azt a maradék embernek. A 4 ember különböző sebességgel képes átkelni a hídon az egyik 10, a másik 5, a harmadik 2 és a negyedik 1 perc alatt. A kérdés, mennyi a legrövidebb idő, ami alatt az átkelés megoldható.
A legrovidebb ut meghatarozasaban az a trukk, hogy a ket leglassabb embernek egyszerre kell atkelnie a hidon mivel igy a masodik leglassab ideje nem szamit bele az utba. Ha atertek mar nem is szabad mozogniuk a ket part kozott.
Ehhez sorba kell oket rendezni es a gyorsabb part atkuldeni elsonek, majd kozuluk valamelyik visszajon (az eredmenyt nem befolyasolja a dontes, hogy melyik). Most elore kell kuldeni a leglassabbakat es a tulpartol megint a leggyorsabb visszajon. Ekkor a ket lassu mar odaat van es a ket gyors meg nem, mar csak nekik kell aterniuk.
Valahogy igy: {1,2} + {1} + {5,10} + {2} + {1,2}
Jeloljuk az embereknek haladasi idejuket t1,t2,t3,t4-vel melyek rendre 1,2,5,10 erteket vesznek fel.
Ha az elobb felvazolt legolcsobb utat kepletre rendezzuk akkor ezt az eredmeny kapjuk
t_min = t1 + 3 * t2 + t4 -> 1 + 3*2 + 10 = 17
A feladathoz ket megoldast keszitettem el az egyikben (GameSpace) lepesenkent haladunk a part kozott es mindig az adott allapottol fuggoen dontunk, hogy ki menjen at. Az egyszerubb megoldasban (SimpleSolution) nincsenek ilyen allapotok a kapott emberek alapjan lefuttatjuk a kepletet es kiirjuk a minimalis koltsegu kombinacionak az erteket, majd a ket part kozotti lepeseket is kiirjuk. Forráskód letöltése
A GameSpace is megkapja a negy embert, majd elkezdi a fent leirt logika alapjan mozgatni az embereket, ember parokat a ket part kozott es menetkozben felirja a haladasi idot. Ha mindenki atert a tulpartra akkor vegeztunk.
A forráskód:
GameSpace.h
#import#import #import @interface GameSpace : NSObject { NSMutableArray * peopleOnTheLeftSide; NSMutableArray * peopleOnTheRightSide; NSMutableArray * slowPair; NSMutableArray * fastPair; NSMutableArray * movingPair; Lamp * theLamp; int elapsedTime; } - (id) initGameSpace; - (void) startWalking; - (void) moveToSide:(Side) side; - (void) printStatus; - (NSMutableArray*) getFastPair; - (NSMutableArray*) getSlowPair; - (NSArray*) sortRightSide; @end
GameSpace.m
#import "GameSpace.h"
@implementation GameSpace
- (id) initGameSpace
{
self = [super init];
if(self)
{
Person * p1 = [[Person alloc] initWithName:@"Anna" AndSpeed:1];
Person * p2 = [[Person alloc] initWithName:@"Bela" AndSpeed:5];
Person * p3 = [[Person alloc] initWithName:@"Nora" AndSpeed:2];
Person * p4 = [[Person alloc] initWithName:@"Dani" AndSpeed:10];
peopleOnTheLeftSide = [[NSMutableArray alloc] initWithCapacity:4];//WithObjects:p1,p2,p3,p4];
[peopleOnTheLeftSide addObject: p1];
[peopleOnTheLeftSide addObject: p2];
[peopleOnTheLeftSide addObject: p3];
[peopleOnTheLeftSide addObject: p4];
//!!!peopleOnTheLeftSide Sort;
peopleOnTheRightSide = [[NSMutableArray alloc] init];
slowPair = [ self getSlowPair];
fastPair = [ self getFastPair];
theLamp = [[Lamp alloc] init];
[theLamp setSide: Left];
elapsedTime = 0;
}
return self;
}
- (void) startWalking
{
while([peopleOnTheLeftSide count] != 0)
{
if([theLamp getSide] == Left)
[self moveToSide:Right];
else
[self moveToSide:Left];
}
}
- (void) moveToSide:(Side) side
{
if([theLamp getSide] == side) return;
switch(side)
{
case Right:
[theLamp setSide: Right];
// move the fast pair
if([peopleOnTheRightSide count] == 0)
{
[theLamp setWhoHasTheLamp:[[fastPair objectAtIndex:0] getName]];
movingPair = fastPair;
}
// slow pair is not there yet
else if([peopleOnTheRightSide count] == 1)
{
[theLamp setWhoHasTheLamp:[[slowPair objectAtIndex:0] getName]];
movingPair = slowPair;
}
// slow pair is there
else if([peopleOnTheRightSide count] == 2)
{
[theLamp setWhoHasTheLamp:[[peopleOnTheLeftSide objectAtIndex:0] getName]];
movingPair = peopleOnTheLeftSide;
}
// add moving pair
for(id p in movingPair)
{
[peopleOnTheRightSide addObject:p];
}
//[peopleOnTheRightSide addObject:[movingPair objectAtIndex:0]];
//[peopleOnTheRightSide addObject:[movingPair objectAtIndex:1]];
elapsedTime += [[movingPair objectAtIndex:1] getSpeed];
if([movingPair isEqualToArray:peopleOnTheLeftSide])
{
[peopleOnTheLeftSide removeAllObjects];
}
else
{
//for(id p in movingPair)
//{
// [peopleOnTheLeftSide removeObject:p];
//}
[peopleOnTheLeftSide removeObject:[movingPair objectAtIndex:0]];
[peopleOnTheLeftSide removeObject:[movingPair objectAtIndex:1]];
}
break;
case Left:
peopleOnTheRightSide = [NSMutableArray arrayWithArray:[self sortRightSide]];
[theLamp setWhoHasTheLamp:[[peopleOnTheRightSide objectAtIndex:0] getName]];
[theLamp setSide: Left];
elapsedTime += [[peopleOnTheRightSide objectAtIndex:0] getSpeed];
[peopleOnTheLeftSide addObject: [peopleOnTheRightSide objectAtIndex:0]];
[peopleOnTheRightSide removeObject:[peopleOnTheRightSide objectAtIndex:0]];
break;
}
[self printStatus];
}
- (NSMutableArray*) getFastPair
{
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Speed"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [peopleOnTheLeftSide sortedArrayUsingDescriptors:sortDescriptors];
Person * fastPerson_1 = [sortedArray objectAtIndex:0];
Person * fastPerson_2 = [sortedArray objectAtIndex:1];
NSMutableArray * result = [[NSMutableArray alloc] initWithCapacity:2];
[result addObject:fastPerson_1];
[result addObject:fastPerson_2];
return result;
}
- (NSMutableArray*) getSlowPair
{
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"Speed"
ascending:YES] autorelease];
NSMutableArray *sortDescriptors = [NSMutableArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [peopleOnTheLeftSide sortedArrayUsingDescriptors:sortDescriptors];
Person * slowPerson_1 = [sortedArray objectAtIndex:2];
Person * slowPerson_2 = [sortedArray objectAtIndex:3];
NSMutableArray * result = [[NSMutableArray alloc] initWithCapacity:2];
[result addObject:slowPerson_1];
[result addObject:slowPerson_2];
return result;
}
- (NSArray*) sortRightSide
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Speed" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
return [peopleOnTheRightSide sortedArrayUsingDescriptors:sortDescriptors];
}
- (void) printStatus
{
for (id people in peopleOnTheLeftSide)
{
NSLog([people getName]);
NSLog(@"%i",[people getSpeed]);
}
NSLog(@" /|______|\\ ");
for (id people in peopleOnTheRightSide) {
NSLog([people getName]);
NSLog(@"%i",[people getSpeed]);
}
NSLog(@"\n=================================================\n");
NSLog(@"%i", elapsedTime);
NSLog(@"\n=================================================\n");
}
@end
Lamp.h
#import#import @interface Lamp : NSObject { Side side; NSString * whoHasTheLamp; } -(void)setSide:(Side)s; -(Side)getSide; -(void) setWhoHasTheLamp:(NSString*)Name; -(NSString*)getWhoHasTheLamp; @end
Lamp.m
#import "Lamp.h"
@implementation Lamp
-(void)setSide:(Side)s;
{
side = s;
}
-(Side)getSide
{
return side;
}
-(void) setWhoHasTheLamp:(NSString*)Name
{
whoHasTheLamp = Name;
}
-(NSString*)getWhoHasTheLamp
{
return whoHasTheLamp;
}
@end
Person.h
@interface Person : NSObject
{
NSString *Name;
int Speed;
}
- (id) initWithName:(NSString*)name AndSpeed:(int)speed;
- (void) setName:(NSString *) name;
- (NSString*) getName;
- (void) setSpeed: (int)speed;
- (int) getSpeed;
@end
Person.m
#import "Person.h"
@implementation Person
- (id) initWithName:(NSString*)name AndSpeed:(int)speed
{
self = [super init];
if(self)
{
[self setName:name];
[self setSpeed:speed];
}
return self;
}
- (void) setName:(NSString*) name
{
Name = name;
}
- (NSString*) getName
{
return Name;
}
- (void) setSpeed:(int) speed
{
Speed = speed;
}
- (int) getSpeed
{
return Speed;
}
@end
Side.h
typedef enum {
Right = 0,
Left
} Side;
SimpleSolution.h
@interface SimpleSolution : NSObject {
NSMutableArray * people;
}
- (id) initSimpleSolution;
- (int) getMinimumTime;
- (NSArray*) sortPeople;
- (void) PrintSolution;
@end
SimpleSolution.m
#import "SimpleSolution.h"
#import "Person.h"
@implementation SimpleSolution
- (id) initSimpleSolution
{
self = [super init];
if(self)
{
Person * p4 = [[Person alloc] initWithName:@"Dani" AndSpeed:10];
Person * p1 = [[Person alloc] initWithName:@"Anna" AndSpeed:1];
Person * p3 = [[Person alloc] initWithName:@"Nora" AndSpeed:2];
Person * p2 = [[Person alloc] initWithName:@"Bela" AndSpeed:5];
people = [[NSMutableArray alloc] initWithCapacity:4];
[people addObject: p1];
[people addObject: p2];
[people addObject: p3];
[people addObject: p4];
}
return self;
}
- (int) getMinimumTime
{
NSArray * sortedArray = [self sortPeople];
return [[sortedArray objectAtIndex:0] getSpeed]
+ [[sortedArray objectAtIndex:1] getSpeed] * 3
+ [[sortedArray objectAtIndex:3] getSpeed];
}
- (NSArray*) sortPeople
{
// comment hogy hogyan lehet rendezni, beepitett lehetosegekkel.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Speed" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
return [people sortedArrayUsingDescriptors:sortDescriptors];
}
// PRINT SCENARIO
- (void) PrintSolution
{
// beszedes kimenet.
NSLog(@"%i",[self getMinimumTime]);
}
@end
main.m
#import#import int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; GameSpace * theGame = [[GameSpace alloc] initGameSpace]; [theGame startWalking]; SimpleSolution * sol = [[SimpleSolution alloc] initSimpleSolution]; [sol PrintSolution]; [pool release]; return 0; }
Szerző: Gal Otto (2013)
Használt fejlesztőkörnyezet: Xcode 4.6.2
Egyszerű számológép storyboard segítségével
>>> SimpleCalculator progam innent letölthető <<<Hozzunk létre egy új projektet és ügyeljünk arra, hogy a storyboard is be legyen pipálva.
A fejlesztői környezetből nyissuk meg a Main.storyboard fájlt. A storyboard-ba huzzuk bele a gombokat a jobb alsó sarokból a drag-n-drop módszert alkalmazva. Formázzuk is meg, nevezzük át, stb. Amikor ezzel elkészültnk, osszuk meg a képernyőt, amit úgy tudunk megtenni, hogy a jobb felső sarok középső ikonját választjuk ki (a csokornyakkendőset), majd jelöljük ki egy objektumot. Ekkor a ctrl+bal egér gombot tartsuk lenyomva és húzzuk bele a ViewController.h fájlba, majd eresszük el és rendeljünk hozzá eseményeket, hasonlóan mint a lenti képen (ügyeljünk arra, hogy ha gombokhoz akciót szeretnénk rendelni, akkor az Connection Outlet helyett az IBAction-t válasszuk, a label-ekhez outlet-et használunk). Ha ezzel megvagyunk, hasonlóan kell kinéznie a fáljnak, mint a ViewController.h. A többi részt fejtsük ki a ViewController.m fájlban hasonlóan, mint ami lejjebb megtalálható.
A továbbfejlestzéshez csak a fantáziánk szabhat határt.
ViewController.h
#import@interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *consoleLabel; @property (weak, nonatomic) IBOutlet UILabel *operatorLabel; - (IBAction)one:(id)sender; - (IBAction)two:(id)sender; - (IBAction)three:(id)sender; - (IBAction)four:(id)sender; - (IBAction)five:(id)sender; - (IBAction)six:(id)sender; - (IBAction)seven:(id)sender; - (IBAction)eight:(id)sender; - (IBAction)nine:(id)sender; - (IBAction)zero:(id)sender; - (IBAction)dot:(id)sender; - (IBAction)clear:(id)sender; - (IBAction)divide:(id)sender; - (IBAction)multiple:(id)sender; - (IBAction)minus:(id)sender; - (IBAction)plus:(id)sender; - (IBAction)sqrt:(id)sender; - (IBAction)suqare:(id)sender; - (IBAction)total:(id)sender; @end
ViewController.m
#import "ViewController.h"
// műveletek deklarálása
typedef enum {
Plus,
Minus,
Multiply,
Divide,
Sqrt,
Square,
Equal
} Operation;
// változók deklarálása
@interface ViewController ()
{
double result;
NSString *store, *log;
int operator;
BOOL isCalculated;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initialize];
}
// inicializáló függvény
- (void)initialize {
result = 0;
store = @"";
log = @"";
isCalculated = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// az 1-es gomb lenyomása hatására történő esemény
- (IBAction)one:(id)sender {
[self addNumberToTheConsole:1];
}
// a 2-es gomb lenyomása hatására történő esemény
- (IBAction)two:(id)sender {
[self addNumberToTheConsole:2];
}
// a 3-as gomb lenyomása hatására történő esemény
- (IBAction)three:(id)sender {
[self addNumberToTheConsole:3];
}
// a 4-es gomb lenyomása hatására történő esemény
- (IBAction)four:(id)sender {
[self addNumberToTheConsole:4];
}
// a 5-ös gomb lenyomása hatására történő esemény
- (IBAction)five:(id)sender {
[self addNumberToTheConsole:5];
}
// a 6-os gomb lenyomása hatására történő esemény
- (IBAction)six:(id)sender {
[self addNumberToTheConsole:6];
}
// a 7-es gomb lenyomása hatására történő esemény
- (IBAction)seven:(id)sender {
[self addNumberToTheConsole:7];
}
// a 8-as gomb lenyomása hatására történő esemény
- (IBAction)eight:(id)sender {
[self addNumberToTheConsole:8];
}
// a 9-es gomb lenyomása hatására történő esemény
- (IBAction)nine:(id)sender {
[self addNumberToTheConsole:9];
}
// a 0 gomb lenyomása hatására történő esemény
- (IBAction)zero:(id)sender {
[self addNumberToTheConsole:0];
}
// a , gomb lenyomása hatására történő esemény
- (IBAction)dot:(id)sender {
store = [store stringByAppendingString:@"."];
log = [log stringByAppendingString:@"."];
[self.consoleLabel setText:store];
[self.operatorLabel setText:log];
}
// a c gomb lenyomása hatására történő esemény
- (IBAction)clear:(id)sender {
store = @"";
log = @"";
result = 0.0;
isCalculated = YES;
[self.consoleLabel setText:@"0"];
[self.operatorLabel setText:log];
}
// a minusz művelet lenyomása hatására történő esemény
- (IBAction)minus:(id)sender {
[self logic:Minus];
}
// a plusz művelet lenyomása hatására történő esemény
- (IBAction)plus:(id)sender {
[self logic:Plus];
}
// a szorzás művelet lenyomása hatására történő esemény
- (IBAction)multiple:(id)sender {
[self logic:Multiply];
}
// az osztás művelet lenyomása hatására történő esemény
- (IBAction)divide:(id)sender {
[self logic:Divide];
}
// a gyökvonás művelet lenyomása hatására történő esemény
- (IBAction)sqrt:(id)sender {
[self logic:Sqrt];
}
// a négyzetreemelés művelet lenyomása hatására történő esemény
- (IBAction)suqare:(id)sender {
[self logic:Square];
}
// az egyenlőség művelet lenyomása hatására történő esemény
- (IBAction)total:(id)sender {
[self logic:Equal];
}
// a logikákat leíró függvény
- (void)logic:(int)type {
double tmpNum = [store doubleValue];
double res = 0.0;
// plusz gomb hatására vonatkozó esemény
if (type == Plus) {
operator = Plus;
result = [store doubleValue];
store = @"";
[self.consoleLabel setText:store];
log = [log stringByAppendingString:@" + "];
[self.operatorLabel setText:log];
}
// minusz gomb hatására vonatkozó esemény
if (type == Minus) {
operator = Minus;
result = [store doubleValue];
store = @"";
[self.consoleLabel setText:store];
log = [log stringByAppendingString:@" - "];
[self.operatorLabel setText:log];
}
// szorzás gomb hatására vonatkozó esemény
if (type == Multiply) {
operator = Multiply;
result = [store doubleValue];
store = @"";
[self.consoleLabel setText:store];
log = [log stringByAppendingString:@" * "];
[self.operatorLabel setText:log];
}
// osztás gomb hatására vonatkozó esemény
if (type == Divide) {
operator = Divide;
result = [store doubleValue];
store = @"";
[self.consoleLabel setText:store];
log = [log stringByAppendingString:@" / "];
[self.operatorLabel setText:log];
}
// gyökvonás gomb hatására vonatkozó esemény
if (type == Sqrt) {
operator = Sqrt;
log = [NSString stringWithFormat:@"sqrt(%f)", tmpNum];
res = sqrt(tmpNum);
store = [NSString stringWithFormat:@"%f", res];
[self.consoleLabel setText:store];
[self.operatorLabel setText:log];
store = @"";
isCalculated = YES;
}
// négyzetre emelés gomb hatására vonatkozó esemény
if (type == Square) {
operator = Square;
log = [NSString stringWithFormat:@"pow(%f, 2)", tmpNum];
res = pow(tmpNum, 2);
store = [NSString stringWithFormat:@"%f", res];
[self.consoleLabel setText:store];
[self.operatorLabel setText:log];
store = @"";
isCalculated = YES;
}
// egyenlőség gomb hatására vonatkozó esemény
if (type == Equal) {
log = @"";
[self.operatorLabel setText:log];
switch (operator) {
case Plus:
res = result + tmpNum;
break;
case Minus:
res = result - tmpNum;
break;
case Multiply:
res = result * tmpNum;
break;
case Divide:
res = result / tmpNum;
break;
default:
break;
}
[self.consoleLabel setText:[NSString stringWithFormat:@"%f", res]];
isCalculated = YES;
}
}
// a console-ra való kiíratás
-(void)addNumberToTheConsole:(int)number{
if (isCalculated) {
log = @"";
store = @"";
isCalculated = !isCalculated;
result = 0;
}
store = [store stringByAppendingString:[NSString stringWithFormat:@"%d", number]];
log = [log stringByAppendingString:[NSString stringWithFormat:@"%d", number]];
[self.consoleLabel setText:store];
[self.operatorLabel setText:log];
}
@end
Szerző: Zsivics Sanel (2014)
Használt fejlesztőkörnyezet: Xcode 5.1
XML Parser használata + lokális értesítések létrehozása iOS rendszeren
>>> A program innen letölthető <<<XMLParser
// Kezdo tagek beolvasasa. Haakkor inicializalom a books tombot, egyebkent ha nem kell csinalni semmit if([elementName isEqualToString:@"Books"]) return; // elemnel hozzaadom a Book elemet a books tombhoz es felszabaditom if([elementName isEqualToString:@"book"]) { [appDelegate.books addObject:aBook]; [aBook release]; aBook = nil; } else [aBook setValue:currentElementValue forKey:elementName]; [currentElementValue release]; currentElementValue = nil; }akkor letrehozok egy uj Book objektumot - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { if([elementName isEqualToString:@"Books"]) { // tomb inicializalasa appDelegate.books = [[NSMutableArray alloc] init]; } else if([elementName isEqualToString:@"book"]) { //Book objektum inicializalasa aBook = [[Book alloc] init]; //Book ID beallitasa az attributumbol aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue]; NSLog(@"id beolvasasa :%i", aBook.bookID); } NSLog(@"Elem feldolgozasa: %@", elementName); } // egy XML elem ertekenk olvasasa karakterenkent - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { // ha ures az aktualis elem, akkor letrehozom if(!currentElementValue) currentElementValue = [[NSMutableString alloc] initWithString:string]; else // egyebkent hozzaadom a karaktert [currentElementValue appendString:string]; NSLog(@"Ertek feldolgozasa: %@", currentElementValue); } // zaro tag feldolgozasa, itt kapja meg a vegleges erteket a Book objektum megfelelo tagja - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { //
Értesítések létrehozása kölcsönzési idő lejárat előtti figyelmeztetéshez:
// letrehozza az ertesiteseket a kolcsonzesi ido lejaratarol, es ertesit rogton a lejart kolcsonzesi hataridokrol.
- (void) setExpires {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// vegig megy a beolvasott konyveken
for (Book* book in books) {
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// date formatter letrehozasa a string -> date konverziohoz, ha a DateFormatter string nem egyezik az XML-ben
// levo date string formatumaval akkor nil objektumot kapunk!
[dateFormatter setDateFormat:@"yyyy.MM.dd"];
//[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Budapest"]];
NSDate *dateFromString = [[NSDate alloc] init];
// \n\r karakterek torlese a datum stringbol
book.expiration = [book.expiration stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// datumma konvertalas
dateFromString = [dateFormatter dateFromString:book.expiration];
// konverzios hiba volt?
if (dateFromString == nil)
{
[self showMsg:[NSString stringWithFormat:@"Hiba tortent a %@ datum konvertalasakor.", book.expiration]];
continue;
}
localNotification.timeZone = [NSTimeZone timeZoneWithName:@"Europe/Budapest"];
// lejart a kolcsonzesi ido?
if ([self isExpired:dateFromString])
{
// ertesitem a felhasznalot
[self showMsg:[NSString stringWithFormat:@"A %@ könyv %@-n már lejárt!", book.title, book.expiration]];
}
else { // kesobb fog lejarni, letrehozom a lejarati ido - 1 nap-ra az ertesitest
dateFromString = [dateFromString dateByAddingTimeInterval:-1*24*60*60];
localNotification.fireDate = dateFromString;
localNotification.alertBody = [NSString stringWithFormat:@"A %s könyv holnap lejár!", book.title];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
}
[dateFormatter release];
}
// letrehozott ertesitesek kiloggolasa
[self logNotifications];
}
Szerző: Fahmi Arman (2014)
Használt fejlesztői környezet: Xcode 4.2
Bináris keresőfa
>>> A program innen letölthető <<<A példaprogram egy bináris keresőfa, amely tetszőleges, összehasonlítható értékű elemek tárolására alkalmas. Rendelkezik beszúrás és törlés műveletekkel, valamint egy inorder bejárás művelettel is. Az inorder bejárás egyben ki is írja az egyes csúcsok értékeit, így rendezett sorozatot kapunk. A program két fő fájlból áll: Node.m és Node.h. Ezen kívül létrehoztam egy main.m fájlt, ami a bináris keresőfa használatát mutatja be.
Node.h
// A C-s include helyett importot használunk #import//Node osztály specifikációja @interface Node : NSObject // minden osztály alapértelmezett ősosztálya az NSObject { //adattagok, alapértelmezetten protected elérésűek Node *left; // bal gyerek Node *right; // jobb gyerek NSObject *data; // a csúcsban tárolt adat } // metódusok deklarációja, amelyeket az implementációban (.m fájl) valósítunk meg // a metódusok neve magába foglalja a paraméterek nevét is // - jel jelöli a példánymetódusokat, + az osztálymetódusokat // a függvénynek két paramétere van: egy Node* és egy NSObject*, visszatérési értéke Node* -(Node*) insertNode:(Node*) root Object:(NSObject*)data; // a függvénynek két paramétere van: egy Node* és egy NSObject*, visszatérési értéke Node* -(Node*) deleteNode:(Node*) root Value:(NSObject*) value; //a függvénynek egy paramétere van: Node* és void visszatérési értékű -(void) inorderTraversal:(Node*) root; // a property kulcsszóval ellátott adattagokhoz automatikusan // getter és setter művelet generálódik, ha az implementációban // synthesize kulcsszóval látjuk el @property (nonatomic, assign) Node *left; // assign jelentése, hogy cím szerinti értékadást szeretnénk biztosítani az adattagnak @property (nonatomic, assign) Node *right; @property (nonatomic, assign) NSObject *data; @end // end kulcsszó jelöli a specifikáció végét
Node.m
// A C-s include helyett importot használunk
#import "Node.h"
@implementation Node // osztály megvalósítását az implementation kulcsszó vezeti be
@synthesize left; // a synthesize kulcsszóval ellátott adattagokhoz automatikus getter és setter művelet generálódik
@synthesize right;
@synthesize data;
// beszúrás művelet, amely a közismert bináris keresőfa beszúrás algoritmusnak megfelelően működik
-(Node*) insertNode:(Node*) root Object:(NSObject*)data
{
Node *current = root;
Node *previous = nil;
Node *temp = [[Node alloc] init]; // temp objektum inicializálása az init művelettel, memóriafoglalás pedig az alloc művelettel
temp.data = data;
temp.left = temp.right = nil; //lehetőség van többszörös értékadásra
if(root == nil) //ha a fa üres, akkor beszúrjuk az első elemet
{
root = temp;
}
else // ha a fa nem üres
{
// végigjárjuk a csúcsokat, megkeressük az új érték helyét
while (current != nil)
{
previous = current;
NSString *strValue2 = (NSString*) current.data;
// ha a beszúrandó érték kisebb, mint az aktuálisan vizsgált elem, akkor balra, egyébként jobbra lépünk a fában
current = ([data compare:current.data options:(NSCaseInsensitiveSearch | NSAnchoredSearch)] == NSOrderedAscending) ? current.left :current.right;
}
if ([data compare:previous.data options:(NSCaseInsensitiveSearch | NSAnchoredSearch)] == NSOrderedAscending)
{
previous.left = temp;
}
else
{
previous.right = temp;
}
}
return root;
}
// érték törlése a fából, amely a közismert bináris keresőfa törlés algoritmusnak megfelelően működik
-(Node*) deleteNode:(Node*) root Value:(NSObject*) value
{
if (root == nil) // ha a fa üres
{
return root;
}
Node *current = root;
Node *parent; //a törléshez meghatározzuk és számontartjuk az keresendő érték szülő csúcsát
while (current != nil && [value compare:current.data options:(NSCaseInsensitiveSearch | NSAnchoredSearch)] != NSOrderedSame )
{
parent = current;
// ha a törlendő érték kisebb, mint az aktuálisan vizsgált elem, akkor balra, egyébként jobbra lépünk a fában
current = [value compare:current.data options:(NSCaseInsensitiveSearch | NSAnchoredSearch)] == NSOrderedAscending ? current.left : current.right;
}
if (current == nil) // ha nem találtuk meg az értéket a fában
{
return root;
}
Node *helper;
Node *suc;
if (current.left == nil) //ha a törlendő csúcs bal részfája üres
{
helper = current.right;
}
else if (current.right == nil) //ha a törlendő csúcs jobb részfája üres
{
helper = current.left;
}
else //ha a törlendő csúcs egyik részfája sem üres
{
suc = current.right;
while (suc.left != nil)
{
suc = suc.left;
}
suc.left = current.left;
helper = current.right;
}
if (parent == nil)
{
return helper;
}
if (current == parent.left)
{
parent.left = helper;
}
else
{
parent.right = helper;
}
current = nil;
return root;
}
// fa bejárása rekurzívan, inorder módon, így rendezett sorozatot kapunk
-(void) inorderTraversal:(Node*)root
{
if(root != nil)
{
// self objektum az aktuális osztálypéldányt tartlmazza, arra hívjuk meg rekurzívan az inorderTraversal műveletet
[self inorderTraversal:root.left];
// NSLog függvény a konzolra írja a megadott adatot, hasonló a használata, mint a printf függvénynak C- ben
NSLog(@"%@ ", root.data);
[self inorderTraversal:root.right];
}
}
@end // az osztály megvalósítását az end kulcsszóval zárjuk
main.m
// A C-s include helyett importot használunk
#import "Node.m"
//main függvény
int main(void)
{
Node *binarySearchTreeString = [[Node alloc] init]; // memóriafoglalás a Node osztály számára, majd példányosítása
Node *rootString = nil; // a C-ből ismert NULL helyett itt nil-t használunk
// tömb inicializálása karakterekkel, memóriafoglalás az alloc művelettel
NSArray *arrayString = [[NSArray alloc] initWithObjects:@"b",@"d",@"c",@"f",@"h",@"x",@"y", nil]; // értékek megadásakor az utolsó elem kötelezően a nil
for (NSObject *val in arrayString) //a C#- ból ismert foreach ciklus megfelelője
{
// a Smalltalk üzenetküldésének mintájára történő metódushívás root és val paraméterekkel
// egyenként hozzáadjuk az array elemeit a fához
rootString=[binarySearchTreeString insertNode:rootString Object:val];
}
// törlés függvény hívása root és "x" paraméterekkel
// a @ jel jelöli az Objective-C objektumokat
[binarySearchTreeString deleteNode:rootString Value:@"x"];
[binarySearchTreeString deleteNode:rootString Value:@"d"];
// fa inorder bejárása, amely a rendezett sorozat képernyőre írását eredményezi
[binarySearchTreeString inorderTraversal:rootString];
Node *binarySearchTreeInt = [[Node alloc] init]; // memóriafoglalás a Node osztály számára, majd példányosítása
Node *rootInt = nil; // a C-ből ismert NULL helyett itt nil-t használunk
// tömb inicializálása egész értékekkel, memóriafoglalás az alloc művelettel
NSArray *arrayInt = [[NSArray alloc] initWithObjects:@"13",@"49",@"51",@"19",@"87",@"33",@"75", nil]; // értékek megadásakor az utolsó elem kötelezően a nil
for (NSObject *val in arrayInt) //a C#- ból ismert foreach ciklus megfelelője
{
// a Smalltalk üzenetküldésének mintájára történő metódushívás root és val paraméterekkel
// egyenként hozzáadjuk az array elemeit a fához
rootInt=[binarySearchTreeInt insertNode:rootInt Object:val];
}
// törlés függvény hívása root és "75" paraméterekkel
// a @ jel jelöli az Objective-C objektumokat
[binarySearchTreeInt deleteNode:rootInt Value:@"75"];
[binarySearchTreeInt deleteNode:rootInt Value:@"19"];
// fa inorder bejárása, amely a rendezett sorozat képernyőre írását eredményezi
[binarySearchTreeInt inorderTraversal:rootInt];
return 0;
}
Szerző: Bereczki Gréta Tamara (2014)
Használt fordító: GNUStep Windows Developer 1.4.0
Reflekciós műveletek
>>> A program innen letölthető <<<A példaprogram futási időben létrehoz egy (ős)osztályt, amelynek van egy darab művelete. Majd létrehozunk egy (gyermek)osztályt (szintén futási időben), amely megöröki ezt a műveletet, majd ebben felüldefiniáljuk az ősosztály műveletét. A példa bemutatja ezen reflekciós eszközök használatát, valamint azt, hogy például el tudjuk érni, hogy a gyermek osztályból a szülő osztály eredeti műveletét hívjuk meg. Lekérdezzük a metódusokat, kiváltsunk metódust, típusellenőrzést végezzünk.
main.m
#import "objc/runtime.h" #importstatic id instanceOfRuntimeSuperClass; static id instanceOfRuntimeSubClass; static Class runtimeSuperClass; static Class runtimeSubClass; //skeleton of the dummy main method static NSString *MainMethod(id self, SEL _cmd) { NSString* className = NSStringFromClass([self class]); return [NSString stringWithFormat: @"This is a MAIN METHOD, from 'MainMethod' method from: %@", className]; } //skeleton of the the dummy sub method static NSString *SubMethod(id self, SEL _cmd) { NSString* className = NSStringFromClass([self class]); return [NSString stringWithFormat: @"This is a SUB METHOD, from 'SubMethod' method from: %@", className]; } //add the given method to the SuperClass by "easy" encoding, (without handwritten signature string) void addMethodToSuperClassByEasyEncoding() { //add the type by getting the info from another class Method description = class_getInstanceMethod([NSObject class], @selector(description)); const char *types = method_getTypeEncoding(description); //now add the method (with signature and implementation) class_addMethod(runtimeSuperClass, @selector(description), (IMP)MainMethod, types); } //create a superclass and its instance void createARuntimeSuperClass() { //Create a superclass runtimeSuperClass = objc_allocateClassPair([NSObject class], "RuntimeSuperClass", 0); //Get classname of runtime class NSString* className = NSStringFromClass([runtimeSuperClass class]); addMethodToSuperClassByEasyEncoding(); //register the class objc_registerClassPair(runtimeSuperClass); //create an instance of the RuntimeClass instanceOfRuntimeSuperClass = [[runtimeSuperClass alloc] init]; NSLog(@"Instance of the SuperClass has been created..."); } void overrideMethodInSubClassByHardEncoding(void) { //add the type by getting the info from another class Method description = class_getInstanceMethod([NSObject class], @selector(description)); //create the signature string for the method NSString *typesNS = [NSString stringWithFormat: @"%s%s%s%s", @encode(NSUInteger), @encode(id), @encode(SEL), @encode(id)]; const char *types = [typesNS UTF8String]; //'override' the 'description' method with the other implementation class_addMethod(runtimeSubClass, @selector(description), (IMP)SubMethod, types); } void createARuntimeSubClass() { //create subclass runtimeSubClass = objc_allocateClassPair([runtimeSuperClass class], "RuntimeSubClass", 0); //register the subclass objc_registerClassPair(runtimeSubClass); //create an instance of the subclass instanceOfRuntimeSubClass = [[runtimeSubClass alloc] init]; //the subclass inherited the method from the superclass NSLog(@"1. call SubClass's method, it will be not yet overridden."); NSLog([instanceOfRuntimeSubClass description]); overrideMethodInSubClassByHardEncoding(); NSLog(@"Instance of the SubClass has been created..."); } void invokeSuperClassMethodFromSubClass() { //create a superclass object from the subclass struct objc_super superClass = { .receiver = instanceOfRuntimeSubClass, .super_class = class_getSuperclass([instanceOfRuntimeSubClass class]) }; //call the superclass's method from subclass NSLog(@"2. call SuperClass's method, from SubClass."); NSLog(objc_msgSendSuper(&superClass, @selector(description))); //call the subclass's changed method NSLog(@"3. call SubClass's overridden method."); NSLog([instanceOfRuntimeSubClass description]); } void checkKindOfSuperClass() { NSLog(@"\n"); //check the kind of superclass's instance if ([instanceOfRuntimeSuperClass isKindOfClass:runtimeSuperClass]) NSLog(@"The type of instanceOfRuntimeSuperclass is RuntimeSuperClass"); else NSLog(@"The type if instanceOfRuntimeSuperClass is not RuntimeSuperClass"); } void checkKindOfSubClass() { NSLog(@"\n"); //check the kind of subclass's instance if ([instanceOfRuntimeSubClass isKindOfClass:runtimeSubClass]) NSLog(@"The type of instanceOfRuntimeSubclass is RuntimeSubClass"); else NSLog(@"The type if instanceOfRuntimeSubClass is not RuntimeSubClass"); } //check the kind of the given instances void checkKindsOfInstances() { checkKindOfSuperClass(); checkKindOfSubClass(); } void getMethodsOfClassInstances() { NSLog(@"\n"); unsigned int numberOfMethods; //get the method list of superclass Method* methods = class_copyMethodList([runtimeSuperClass class], &numberOfMethods); //print the methods from the list NSLog(@"The superclass has: %d method(s)", numberOfMethods); for (int i = 0; i < numberOfMethods; i++) NSLog(@"Method name: %@", NSStringFromSelector(method_getName(methods[i]))); //get the method list from subclass methods = class_copyMethodList([runtimeSubClass class], &numberOfMethods); //print the methods NSLog(@"The subclass has: %d method(s)", numberOfMethods); for (int i = 0; i < numberOfMethods; i++) NSLog(@"Method name: %@", NSStringFromSelector(method_getName(methods[i]))); } int main(int argc, const char * argv[]) { @autoreleasepool { createARuntimeSuperClass(); createARuntimeSubClass(); invokeSuperClassMethodFromSubClass(); checkKindsOfInstances(); getMethodsOfClassInstances(); } return 0; }
Szerző: Siklósi Benjamin (2014)
Használt fordító: XCode 5.1