Objective-C-Kurzanleitung

Objective-C ist eine Allzwecksprache, die zusätzlich zur Programmiersprache C entwickelt wird, indem Funktionen der Programmiersprache Small Talk hinzugefügt werden, die sie zu einer objektorientierten Sprache machen. Es wird hauptsächlich zur Entwicklung von iOS- und Mac OS X-Betriebssystemen sowie deren Anwendungen verwendet.

Ursprünglich wurde Objective-C von NeXT für sein NeXTSTEP-Betriebssystem entwickelt, von dem es von Apple für iOS und Mac OS X übernommen wurde.

Objekt orientierte Programmierung

Unterstützt voll und ganz die objektorientierte Programmierung, einschließlich der vier Säulen der objektorientierten Entwicklung -

  • Encapsulation
  • Daten verstecken
  • Inheritance
  • Polymorphism

Beispielcode

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   NSLog (@"hello world");
   [pool drain];
   return 0;
}

Foundation Framework

Foundation Framework bietet eine Vielzahl von Funktionen, die unten aufgeführt sind.

  • Es enthält eine Liste erweiterter Datentypen wie NSArray, NSDictionary, NSSet usw.

  • Es besteht aus einer Vielzahl von Funktionen, mit denen Dateien, Zeichenfolgen usw. bearbeitet werden können.

  • Es bietet Funktionen für die URL-Behandlung, Dienstprogramme wie Datumsformatierung, Datenbehandlung, Fehlerbehandlung usw.

Lernziel-C

Das Wichtigste beim Erlernen von Objective-C ist, sich auf Konzepte zu konzentrieren und sich nicht in sprachtechnischen Details zu verlieren.

Der Zweck des Lernens einer Programmiersprache besteht darin, ein besserer Programmierer zu werden. das heißt, beim Entwerfen und Implementieren neuer Systeme und beim Verwalten alter Systeme effektiver zu werden.

Verwendung von Objective-C

Objective-C wird, wie bereits erwähnt, in iOS und Mac OS X verwendet. Es hat eine große Anzahl von iOS-Benutzern und eine große Anzahl von Mac OS X-Benutzern. Und da Apple sich zuerst auf Qualität konzentriert und es wunderbar für diejenigen ist, die angefangen haben, Objective-C zu lernen.

Einrichtung der lokalen Umgebung

Wenn Sie weiterhin bereit sind, Ihre Umgebung für die Programmiersprache Objective-C einzurichten, benötigen Sie die folgenden zwei auf Ihrem Computer verfügbaren Softwareprogramme: (a) Texteditor und (b) GCC-Compiler.

Texteditor

Dies wird verwendet, um Ihr Programm einzugeben. Beispiele für wenige Editoren sind Windows Notepad, OS Edit-Befehl, Brief, Epsilon, EMACS und vim oder vi.

Name und Version des Texteditors können auf verschiedenen Betriebssystemen variieren. Beispielsweise wird Notepad unter Windows verwendet, und vim oder vi können sowohl unter Windows als auch unter Linux oder UNIX verwendet werden.

Die Dateien, die Sie mit Ihrem Editor erstellen, werden als Quelldateien bezeichnet und enthalten Programmquellcode. Die Quelldateien für Objective-C-Programme werden normalerweise mit der Erweiterung ".m".

Stellen Sie vor Beginn der Programmierung sicher, dass Sie über einen Texteditor verfügen und über genügend Erfahrung verfügen, um ein Computerprogramm zu schreiben, in einer Datei zu speichern, zu kompilieren und schließlich auszuführen.

Der GCC-Compiler

Der in die Quelldatei geschriebene Quellcode ist die vom Menschen lesbare Quelle für Ihr Programm. Es muss "kompiliert" werden, damit es in Maschinensprache umgewandelt werden kann, damit Ihre CPU das Programm gemäß den gegebenen Anweisungen tatsächlich ausführen kann.

Dieser GCC-Compiler wird verwendet, um Ihren Quellcode in das endgültige ausführbare Programm zu kompilieren. Ich gehe davon aus, dass Sie Grundkenntnisse über einen Programmiersprachen-Compiler haben.

Der GCC-Compiler ist auf verschiedenen Plattformen kostenlos verfügbar. Die Einrichtung auf verschiedenen Plattformen wird nachfolgend erläutert.

Installation unter UNIX / Linux

Der erste Schritt ist die Installation von gcc zusammen mit dem gcc Objective-C-Paket. Dies geschieht durch -

$ su - $ yum install gcc
$ yum install gcc-objc

Der nächste Schritt besteht darin, Paketabhängigkeiten mit dem folgenden Befehl einzurichten:

$ yum install make libpng libpng-devel libtiff libtiff-devel libobjc 
   libxml2 libxml2-devel libX11-devel libXt-devel libjpeg libjpeg-devel

Laden Sie GNUStep herunter und installieren Sie es, um alle Funktionen von Objective-C zu erhalten. Dies kann durch Herunterladen des Pakets von erfolgenhttp://main.gnustep.org/resources/downloads.php.

Jetzt müssen wir zum heruntergeladenen Ordner wechseln und die Datei entpacken, indem wir -

$ tar xvfz gnustep-startup-
      
       .tar.gz 
      

Jetzt müssen wir zu dem Ordner gnustep-startup wechseln, der mit - erstellt wird.

$ cd gnustep-startup-<version>

Als nächstes müssen wir den Erstellungsprozess konfigurieren -

$ ./configure

Dann können wir bauen durch -

$ make

Wir müssen endlich die Umwelt einrichten, indem wir -

$ . /usr/GNUstep/System/Library/Makefiles/GNUstep.sh

Wir haben ein helloWorld.m Objective-C wie folgt -

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
   NSLog (@"hello world");
   [pool drain];
   return 0;
}

Jetzt können wir eine Objective-C-Datei kompilieren und ausführen, z. B. helloWorld.m, indem wir mit cd in einen Ordner mit der Datei wechseln und dann die folgenden Schritte ausführen:

$ gcc `gnustep-config --objc-flags` 
-L/usr/GNUstep/Local/Library/Libraries 
-lgnustep-base helloWorld.m -o helloWorld
$ ./helloWorld

Wir können die folgende Ausgabe sehen -

2013-09-07 10:48:39.772 tutorialsPoint[12906] hello world

Installation unter Mac OS

Wenn Sie Mac OS X verwenden, können Sie GCC am einfachsten herunterladen, indem Sie die Xcode-Entwicklungsumgebung von der Apple-Website herunterladen und die einfachen Installationsanweisungen befolgen. Sobald Sie Xcode eingerichtet haben, können Sie den GNU-Compiler für C / C ++ verwenden.

Xcode ist derzeit unter developer.apple.com/technologies/tools/ verfügbar .

Installation unter Windows

Um das Objective-C-Programm unter Windows ausführen zu können, müssen MinGW und GNUStep Core installiert werden. Beide sind erhältlich beihttps://www.gnu.org/software/gnustep/windows/installer.html.

Zuerst müssen wir das MSYS / MinGW-Systempaket installieren. Dann müssen wir das GNUstep Core-Paket installieren. Beide bieten ein Windows-Installationsprogramm, das selbsterklärend ist.

Um dann Objective-C und GNUstep zu verwenden, wählen Sie Start -> Alle Programme -> GNUstep -> Shell

Wechseln Sie in den Ordner mit helloWorld.m

Wir können das Programm mit - kompilieren

$ gcc `gnustep-config --objc-flags` 
-L /GNUstep/System/Library/Libraries hello.m -o hello -lgnustep-base -lobjc

Wir können das Programm ausführen, indem wir - verwenden

./hello.exe

Wir erhalten die folgende Ausgabe -

2013-09-07 10:48:39.772 tutorialsPoint[1200] hello world

Bevor wir uns mit den Grundbausteinen der Programmiersprache Objective-C befassen, wollen wir uns eine minimale Objective-C-Programmstruktur ansehen, damit wir sie in den kommenden Kapiteln als Referenz verwenden können.

Objective-C Hallo Welt Beispiel

Ein Objective-C-Programm besteht im Wesentlichen aus folgenden Teilen:

  • Präprozessorbefehle
  • Interface
  • Implementation
  • Method
  • Variables
  • Aussagen & Ausdrücke
  • Comments

Schauen wir uns einen einfachen Code an, der die Wörter "Hello World" druckt -

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass

- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

@end

int main() {
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   return 0;
}

Schauen wir uns verschiedene Teile des obigen Programms an -

  • Die erste Zeile des Programms #import <Foundation / Foundation.h> ist ein Präprozessorbefehl, der einen Objective-C-Compiler anweist , die Datei Foundation.h einzuschließen, bevor er zur eigentlichen Kompilierung übergeht .

  • Die nächste Zeile @interface SampleClass: NSObject zeigt, wie eine Schnittstelle erstellt wird. Es erbt NSObject, die Basisklasse aller Objekte.

  • Die nächste Zeile - (void) sampleMethod; zeigt, wie eine Methode deklariert wird.

  • Die nächste Zeile @end markiert das Ende einer Schnittstelle.

  • Die nächste Zeile @implementation SampleClass zeigt, wie die Schnittstelle SampleClass implementiert wird.

  • Die nächste Zeile - (void) sampleMethod {} zeigt die Implementierung der sampleMethod.

  • Die nächste Zeile @end markiert das Ende einer Implementierung.

  • Die nächste Zeile int main () ist die Hauptfunktion, mit der die Programmausführung beginnt.

  • Die nächste Zeile /*...*/ wird vom Compiler ignoriert und es wurden zusätzliche Kommentare zum Programm hinzugefügt. Solche Zeilen werden im Programm als Kommentare bezeichnet.

  • Die nächste Zeile NSLog (...) ist eine weitere in Objective-C verfügbare Funktion, die die Meldung "Hallo Welt!" auf dem Bildschirm angezeigt werden.

  • Die nächste Zeile return 0; Beendet die Funktion main () und gibt den Wert 0 zurück.

Kompilieren und Ausführen des Objective-C-Programms

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2017-10-06 07:48:32.020 demo[65832] Hello, World!

Sie haben eine Grundstruktur des Objective-C-Programms gesehen, sodass andere Grundbausteine ​​der Objective-C-Programmiersprache leicht zu verstehen sind.

Token in Ziel-C

Ein Objective-C-Programm besteht aus verschiedenen Token, und ein Token ist entweder ein Schlüsselwort, ein Bezeichner, eine Konstante, ein Zeichenfolgenliteral oder ein Symbol. Die folgende Objective-C-Anweisung besteht beispielsweise aus sechs Token:

NSLog(@"Hello, World! \n");

Die einzelnen Token sind -

NSLog
@
(
   "Hello, World! \n"
)
;

Semikolons;

Im Objective-C-Programm ist das Semikolon ein Anweisungsabschluss. Das heißt, jede einzelne Anweisung muss mit einem Semikolon abgeschlossen werden. Es zeigt das Ende einer logischen Entität an.

Es folgen beispielsweise zwei verschiedene Aussagen:

NSLog(@"Hello, World! \n");
return 0;

Bemerkungen

Kommentare sind wie Hilfetexte in Ihrem Objective-C-Programm und werden vom Compiler ignoriert. Sie beginnen mit / * und enden mit den Zeichen * / wie unten gezeigt -

/* my first program in Objective-C */

Sie können keine Kommentare mit in Kommentaren haben und sie kommen nicht in Zeichenfolgen- oder Zeichenliteralen vor.

Kennungen

Ein Objective-C-Bezeichner ist ein Name, der zum Identifizieren einer Variablen, Funktion oder eines anderen benutzerdefinierten Elements verwendet wird. Ein Bezeichner beginnt mit einem Buchstaben A bis Z oder a bis z oder einem Unterstrich _, gefolgt von null oder mehr Buchstaben, Unterstrichen und Ziffern (0 bis 9).

Objective-C erlaubt keine Interpunktionszeichen wie @, $ und% in Bezeichnern. Ziel-C ist acase-sensitiveProgrammiersprache. So Manpower und Manpower sind zwei verschiedene Kennungen in Objective-C. Hier sind einige Beispiele für akzeptable Bezeichner -

mohd       zara    abc   move_name  a_123
myname50   _temp   j     a23b9      retVal

Schlüsselwörter

Die folgende Liste zeigt einige der reservierten Wörter in Objective-C. Diese reservierten Wörter dürfen nicht als Konstante, Variable oder andere Bezeichnernamen verwendet werden.

Auto sonst lange Schalter
Unterbrechung Aufzählung registrieren typedef
Fall extern Rückkehr Union
verkohlen schweben kurz ohne Vorzeichen
const zum unterzeichnet Leere
fortsetzen gehe zu Größe von flüchtig
Standard wenn statisch während
tun int struct _Packed
doppelt Protokoll Schnittstelle Implementierung
NSObject NSInteger NSNumber CGFloat
Eigentum nichtatomar; behalten stark
schwach unsafe_unretained; lesen Schreiben schreibgeschützt

Leerzeichen in Objective-C

Eine Zeile, die nur Leerzeichen enthält, möglicherweise mit einem Kommentar, wird als Leerzeile bezeichnet, und ein Objective-C-Compiler ignoriert sie vollständig.

Leerzeichen ist der Begriff, der in Objective-C verwendet wird, um Leerzeichen, Tabulatoren, Zeilenumbrüche und Kommentare zu beschreiben. Whitespace trennt einen Teil einer Anweisung von einem anderen und ermöglicht dem Compiler zu identifizieren, wo ein Element in einer Anweisung, wie z. B. int, endet und das nächste Element beginnt. Daher in der folgenden Aussage -

int age;

Es muss mindestens ein Leerzeichen (normalerweise ein Leerzeichen) zwischen int und age vorhanden sein, damit der Compiler sie unterscheiden kann. Auf der anderen Seite, in der folgenden Aussage,

fruit = apples + oranges;   // get the total fruit

Zwischen Obst und = oder zwischen = und Äpfeln sind keine Leerzeichen erforderlich, obwohl Sie einige hinzufügen können, wenn Sie dies aus Gründen der Lesbarkeit wünschen.

In der Programmiersprache Objective-C beziehen sich Datentypen auf ein umfangreiches System zum Deklarieren von Variablen oder Funktionen verschiedener Typen. Der Typ einer Variablen bestimmt, wie viel Speicherplatz sie einnimmt und wie das gespeicherte Bitmuster interpretiert wird.

Die Typen in Objective-C können wie folgt klassifiziert werden:

Sr.Nr. Typen & Beschreibung
1

Basic Types −

Sie sind arithmetische Typen und bestehen aus zwei Typen: (a) ganzzahlige Typen und (b) Gleitkommatypen.

2

Enumerated types −

Sie sind wieder arithmetische Typen und werden verwendet, um Variablen zu definieren, denen im gesamten Programm nur bestimmte diskrete ganzzahlige Werte zugewiesen werden können.

3

The type void −

Der Typbezeichner void gibt an, dass kein Wert verfügbar ist.

4

Derived types −

Sie umfassen (a) Zeigertypen, (b) Array-Typen, (c) Strukturtypen, (d) Unionstypen und (e) Funktionstypen.

Die Array- und Strukturtypen werden zusammen als Aggregattypen bezeichnet. Der Typ einer Funktion gibt den Typ des Rückgabewerts der Funktion an. Wir werden im folgenden Abschnitt grundlegende Typen sehen, während andere Typen in den kommenden Kapiteln behandelt werden.

Ganzzahlige Typen

Die folgende Tabelle enthält Details zu Standard-Integer-Typen mit ihren Speichergrößen und Wertebereichen.

Art Speichergröße Wertebereich
verkohlen 1 Byte -128 bis 127 oder 0 bis 255
vorzeichenloser char 1 Byte 0 bis 255
signierter char 1 Byte -128 bis 127
int 2 oder 4 Bytes -32.768 bis 32.767 oder -2.147.483.648 bis 2.147.483.647
unsigned int 2 oder 4 Bytes 0 bis 65.535 oder 0 bis 4.294.967.295
kurz 2 Bytes -32.768 bis 32.767
unsigned short 2 Bytes 0 bis 65.535
lange 4 Bytes -2.147.483.648 bis 2.147.483.647
lange nicht signiert 4 Bytes 0 bis 4,294,967,295

Um die genaue Größe eines Typs oder einer Variablen auf einer bestimmten Plattform zu erhalten, können Sie die verwenden sizeofOperator. Der Ausdruck sizeof (Typ) gibt die Speichergröße des Objekts oder Typs in Bytes an. Im Folgenden finden Sie ein Beispiel, um die Größe des int-Typs auf einem beliebigen Computer zu ermitteln.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for int : %d \n", sizeof(int));
   return 0;
}

Wenn Sie das obige Programm kompilieren und ausführen, wird unter Linux das folgende Ergebnis erzielt:

2013-09-07 22:21:39.155 demo[1340] Storage size for int : 4

Gleitkommatypen

Die folgende Tabelle enthält Details zu Standard-Gleitkommatypen mit Speichergrößen und Wertebereichen sowie deren Genauigkeit.

Art Speichergröße Wertebereich Präzision
schweben 4 Byte 1,2E-38 bis 3,4E + 38 6 Dezimalstellen
doppelt 8 Byte 2,3E-308 bis 1,7E + 308 15 Dezimalstellen
langes Doppel 10 Byte 3.4E-4932 bis 1.1E + 4932 19 Dezimalstellen

Die Header-Datei float.h definiert Makros, mit denen Sie diese Werte und andere Details zur binären Darstellung von reellen Zahlen in Ihren Programmen verwenden können. Im folgenden Beispiel wird der von einem Float-Typ belegte Speicherplatz und seine Bereichswerte gedruckt.

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for float : %d \n", sizeof(float));
   return 0;
}

Wenn Sie das obige Programm kompilieren und ausführen, wird unter Linux das folgende Ergebnis erzielt:

2013-09-07 22:22:21.729 demo[3927] Storage size for float : 4

Der leere Typ

Der void-Typ gibt an, dass kein Wert verfügbar ist. Es wird in drei Arten von Situationen verwendet -

Sr.Nr. Typen und Beschreibung
1 Function returns as void

In Objective-C gibt es verschiedene Funktionen, die keinen Wert zurückgeben, oder Sie können sagen, dass sie void zurückgeben. Eine Funktion ohne Rückgabewert hat den Rückgabetyp als ungültig. Zum Beispiel,void exit (int status);

2 Function arguments as void

In Objective-C gibt es verschiedene Funktionen, die keine Parameter akzeptieren. Eine Funktion ohne Parameter kann als ungültig akzeptiert werden. Zum Beispiel,int rand(void);

Der Leertyp wird Ihnen zu diesem Zeitpunkt möglicherweise nicht verstanden. Lassen Sie uns fortfahren und wir werden diese Konzepte in den kommenden Kapiteln behandeln.

Eine Variable ist nichts anderes als ein Name für einen Speicherbereich, den unsere Programme bearbeiten können. Jede Variable in Objective-C hat einen bestimmten Typ, der die Größe und das Layout des Speichers der Variablen bestimmt. den Wertebereich, der in diesem Speicher gespeichert werden kann; und die Menge von Operationen, die auf die Variable angewendet werden können.

Der Name einer Variablen kann aus Buchstaben, Ziffern und dem Unterstrich bestehen. Es muss entweder mit einem Buchstaben oder einem Unterstrich beginnen. Groß- und Kleinbuchstaben unterscheiden sich, da bei Objective-C zwischen Groß- und Kleinschreibung unterschieden wird. Basierend auf den im vorherigen Kapitel erläuterten Grundtypen gibt es die folgenden Grundvariablentypen:

Sr.Nr. Typ & Beschreibung
1

char

Normalerweise ein einzelnes Oktett (ein Byte). Dies ist ein ganzzahliger Typ.

2

int

Die natürlichste Ganzzahlgröße für die Maschine.

3

float

Ein Gleitkommawert mit einfacher Genauigkeit.

4

double

Ein Gleitkommawert mit doppelter Genauigkeit.

5

void

Stellt das Fehlen eines Typs dar.

Mit der Programmiersprache Objective-C können auch verschiedene andere Variablentypen definiert werden, die in den folgenden Kapiteln wie Aufzählung, Zeiger, Array, Struktur, Vereinigung usw. behandelt werden. In diesem Kapitel werden nur grundlegende Variablentypen untersucht.

Variablendefinition in Ziel-C

Eine Variablendefinition bedeutet, dem Compiler mitzuteilen, wo und wie viel Speicher für die Variable erstellt werden soll. Eine Variablendefinition gibt einen Datentyp an und enthält eine Liste einer oder mehrerer Variablen dieses Typs wie folgt:

type variable_list;

Hier, type muss ein gültiger Objective-C-Datentyp sein, einschließlich char, w_char, int, float, double, bool oder eines benutzerdefinierten Objekts usw., und variable_listkann aus einem oder mehreren durch Kommas getrennten Bezeichnernamen bestehen. Einige gültige Erklärungen werden hier angezeigt -

int    i, j, k;
char   c, ch;
float  f, salary;
double d;

Die Linie int i, j, k;beide deklarieren und definieren die Variablen i, j und k; Dies weist den Compiler an, Variablen mit den Namen i, j und k vom Typ int zu erstellen.

Variablen können in ihrer Deklaration initialisiert (mit einem Anfangswert versehen) werden. Der Initialisierer besteht aus einem Gleichheitszeichen, gefolgt von einem konstanten Ausdruck wie folgt:

type variable_name = value;

Einige Beispiele sind -

extern int d = 3, f = 5;    // declaration of d and f. 
int d = 3, f = 5;           // definition and initializing d and f. 
byte z = 22;                // definition and initializes z. 
char x = 'x';               // the variable x has the value 'x'.

Für die Definition ohne Initialisierer: Variablen mit statischer Speicherdauer werden implizit mit NULL initialisiert (alle Bytes haben den Wert 0). Der Anfangswert aller anderen Variablen ist undefiniert.

Variablendeklaration in Ziel-C

Eine Variablendeklaration gibt dem Compiler die Gewissheit, dass eine Variable mit dem angegebenen Typ und Namen vorhanden ist, sodass der Compiler mit der weiteren Kompilierung fortfahren kann, ohne vollständige Details über die Variable zu benötigen. Eine Variablendeklaration hat nur zum Zeitpunkt der Kompilierung ihre Bedeutung. Der Compiler benötigt zum Zeitpunkt der Verknüpfung des Programms eine tatsächliche Variablendeklaration.

Eine Variablendeklaration ist nützlich, wenn Sie mehrere Dateien verwenden und Ihre Variable in einer der Dateien definieren, die zum Zeitpunkt der Verknüpfung des Programms verfügbar sind. Du wirst benutzenexternSchlüsselwort, um eine Variable an einer beliebigen Stelle zu deklarieren. Sie können eine Variable in Ihrem Objective-C-Programm zwar mehrmals deklarieren, sie kann jedoch nur einmal in einer Datei, einer Funktion oder einem Codeblock definiert werden.

Beispiel

Versuchen Sie das folgende Beispiel, in dem Variablen oben deklariert, aber innerhalb der Hauptfunktion definiert und initialisiert wurden.

#import <Foundation/Foundation.h>

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main () {
  /* variable definition: */
  int a, b;
  int c;
  float f;
 
  /* actual initialization */
  a = 10;
  b = 20;
  
  c = a + b;
  NSLog(@"value of c : %d \n", c);

  f = 70.0/3.0;
  NSLog(@"value of f : %f \n", f);
 
  return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-07 22:43:31.695 demo[14019] value of c : 30 
2013-09-07 22:43:31.695 demo[14019] value of f : 23.333334

Das gleiche Konzept gilt für die Funktionsdeklaration, bei der Sie zum Zeitpunkt der Deklaration einen Funktionsnamen angeben und dessen tatsächliche Definition an einer anderen Stelle angegeben werden kann. Im folgenden Beispiel wird die Verwendung der C-Funktion erläutert. Wie Sie wissen, unterstützt Objective-C auch Funktionen im C-Stil.

// function declaration
int func();

int main() {
   // function call
   int i = func();
}

// function definition
int func() {
   return 0;
}

L-Werte und R-Werte in Ziel-C

In Objective-C gibt es zwei Arten von Ausdrücken:

  • lvalue- Ausdrücke, die sich auf einen Speicherort beziehen, werden als "lvalue" -Ausdruck bezeichnet. Ein Wert kann entweder als linke oder rechte Seite einer Zuweisung angezeigt werden.

  • rvalue- Der Begriff rWert bezieht sich auf einen Datenwert, der an einer bestimmten Adresse im Speicher gespeichert ist. Ein r-Wert ist ein Ausdruck, dem kein Wert zugewiesen werden kann. Dies bedeutet, dass ein r-Wert möglicherweise auf der rechten, aber nicht auf der linken Seite einer Zuweisung angezeigt wird.

Variablen sind l-Werte und können daher auf der linken Seite einer Zuweisung angezeigt werden. Numerische Literale sind r-Werte und können daher nicht zugewiesen werden und nicht auf der linken Seite angezeigt werden. Es folgt eine gültige Aussage -

int g = 20;

Das Folgende ist jedoch keine gültige Anweisung und würde einen Fehler bei der Kompilierung verursachen.

10 = 20;

Die Konstanten beziehen sich auf feste Werte, die das Programm während seiner Ausführung möglicherweise nicht ändert. Diese festen Werte werden auch genanntliterals.

Konstanten können von einem der grundlegenden Datentypen sein, z. B. eine Ganzzahlkonstante, eine Floating-Konstante, eine Zeichenkonstante oder ein Zeichenfolgenliteral . Es gibt auch Aufzählungskonstanten.

Das constants werden wie reguläre Variablen behandelt, außer dass ihre Werte nach ihrer Definition nicht mehr geändert werden können.

Ganzzahlige Literale

Ein ganzzahliges Literal kann eine Dezimal-, Oktal- oder Hexadezimalkonstante sein. Ein Präfix gibt die Basis oder den Radix an: 0x oder 0X für Hexadezimal, 0 für Oktal und nichts für Dezimal.

Ein ganzzahliges Literal kann auch ein Suffix haben, das eine Kombination aus U und L für unsigned bzw. long ist. Das Suffix kann in Groß- oder Kleinbuchstaben und in beliebiger Reihenfolge angegeben werden.

Hier sind einige Beispiele für ganzzahlige Literale -

212         /* Legal */
215u        /* Legal */
0xFeeL      /* Legal */
078         /* Illegal: 8 is not an octal digit */
032UU       /* Illegal: cannot repeat a suffix */

Im Folgenden finden Sie weitere Beispiele für verschiedene Arten von Integer-Literalen:

85         /* decimal */
0213       /* octal */
0x4b       /* hexadecimal */
30         /* int */
30u        /* unsigned int */
30l        /* long */
30ul       /* unsigned long */

Gleitkomma-Literale

Ein Gleitkomma-Literal besteht aus einem ganzzahligen Teil, einem Dezimalpunkt, einem Bruchteil und einem Exponententeil. Sie können Gleitkomma-Literale entweder in Dezimalform oder in Exponentialform darstellen.

Bei der Darstellung in Dezimalform müssen Sie den Dezimalpunkt, den Exponenten oder beides angeben. Bei der Darstellung in Exponentialform müssen Sie den ganzzahligen Teil, den Bruchteil oder beides einschließen. Der vorzeichenbehaftete Exponent wird durch e oder E eingeführt.

Hier einige Beispiele für Gleitkomma-Literale -

3.14159       /* Legal */
314159E-5L    /* Legal */
510E          /* Illegal: incomplete exponent */
210f          /* Illegal: no decimal or exponent */
.e55          /* Illegal: missing integer or fraction */

Zeichenkonstanten

Zeichenliterale werden in einfache Anführungszeichen gesetzt, z. B. 'x', und können in einer einfachen Variablen von gespeichert werden char Art.

Ein Zeichenliteral kann ein einfaches Zeichen (z. B. 'x'), eine Escape-Sequenz (z. B. '\ t') oder ein universelles Zeichen (z. B. '\ u02C0') sein.

Es gibt bestimmte Zeichen in C, wenn sie mit einem Backslash versehen werden. Sie haben eine besondere Bedeutung und werden zur Darstellung wie Zeilenumbruch (\ n) oder Tabulator (\ t) verwendet. Hier haben Sie eine Liste einiger solcher Escape-Sequenzcodes -

Fluchtabfolge Bedeutung
\\ \ Zeichen
\ ' 'Charakter
"" "Charakter
\? ? Charakter
\ein Alarm oder Glocke
\ b Rücktaste
\ f Formularvorschub
\ n Neue Zeile
\ r Wagenrücklauf
\ t Horizontale Registerkarte
\ v Vertikale Registerkarte
\ ooo Oktalzahl von ein bis drei Ziffern
\ xhh. . . Hexadezimalzahl aus einer oder mehreren Ziffern

Das folgende Beispiel zeigt einige Escape-Zeichen -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Hello\tWorld\n\n");
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-07 22:17:17.923 demo[17871] Hello	World

String-Literale

String-Literale oder Konstanten werden in doppelte Anführungszeichen "" eingeschlossen. Eine Zeichenfolge enthält Zeichen, die Zeichenliteralen ähnlich sind: einfache Zeichen, Escape-Sequenzen und universelle Zeichen.

Sie können eine lange Zeile mithilfe von Zeichenfolgenliteralen in mehrere Zeilen aufteilen und diese durch Leerzeichen trennen.

Hier sind einige Beispiele für String-Literale. Alle drei Formen sind identische Zeichenfolgen.

"hello, dear"

"hello, \

dear"

"hello, " "d" "ear"

Konstanten definieren

In C gibt es zwei einfache Möglichkeiten, Konstanten zu definieren:

  • Verwenden von #define Präprozessor.

  • Verwenden von const Stichwort.

Der Präprozessor #define

Das folgende Formular verwendet den Präprozessor #define, um eine Konstante zu definieren -

#define identifier value

Das folgende Beispiel erklärt es im Detail -

#import <Foundation/Foundation.h>

#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'

int main() {
   int area;
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-07 22:18:16.637 demo[21460] value of area : 50
2013-09-07 22:18:16.638 demo[21460]

Das const-Schlüsselwort

Sie können verwenden const Präfix zum Deklarieren von Konstanten mit einem bestimmten Typ wie folgt:

const type variable = value;

Das folgende Beispiel erklärt es im Detail -

#import <Foundation/Foundation.h>

int main() {
   const int  LENGTH = 10;
   const int  WIDTH  = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-07 22:19:24.780 demo[25621] value of area : 50
2013-09-07 22:19:24.781 demo[25621]

Beachten Sie, dass es eine gute Programmierpraxis ist, Konstanten in GROSSBUCHSTABEN zu definieren.

Ein Operator ist ein Symbol, das den Compiler anweist, bestimmte mathematische oder logische Manipulationen durchzuführen. Die Objective-C-Sprache ist reich an integrierten Operatoren und bietet die folgenden Arten von Operatoren:

  • Rechenzeichen
  • Vergleichsoperatoren
  • Logische Operatoren
  • Bitweise Operatoren
  • Zuweisungsoperatoren
  • Verschiedene Operatoren

In diesem Tutorial werden die arithmetischen, relationalen, logischen, bitweisen, Zuweisungs- und anderen Operatoren nacheinander erläutert.

Rechenzeichen

Die folgende Tabelle zeigt alle arithmetischen Operatoren, die von der Sprache Objective-C unterstützt werden. Variable annehmenA hält 10 und variabel B hält 20, dann -

Beispiele anzeigen

Operator Beschreibung Beispiel
+ Fügt zwei Operanden hinzu A + B ergibt 30
- - Subtrahiert den zweiten Operanden vom ersten A - B ergibt -10
* * Multipliziert beide Operanden A * B ergibt 200
/. Teilt den Zähler durch den Nenner B / A ergibt 2
%. Modul Operator und Rest nach einer ganzzahligen Division B% A ergibt 0
++ Der Inkrementierungsoperator erhöht den ganzzahligen Wert um eins A ++ gibt 11
- - Der Dekrementierungsoperator verringert den ganzzahligen Wert um eins A-- wird 9 geben

Vergleichsoperatoren

Die folgende Tabelle zeigt alle relationalen Operatoren, die von der Objective-C-Sprache unterstützt werden. Variable annehmenA hält 10 und variabel B hält 20, dann -

Beispiele anzeigen

Operator Beschreibung Beispiel
== Überprüft, ob die Werte von zwei Operanden gleich sind oder nicht. Wenn ja, dann wird die Bedingung wahr. (A == B) ist nicht wahr.
! = Überprüft, ob die Werte von zwei Operanden gleich sind oder nicht. Wenn die Werte nicht gleich sind, wird die Bedingung wahr. (A! = B) ist wahr.
> Überprüft, ob der Wert des linken Operanden größer als der Wert des rechten Operanden ist. Wenn ja, dann wird die Bedingung wahr. (A> B) ist nicht wahr.
< Überprüft, ob der Wert des linken Operanden kleiner als der Wert des rechten Operanden ist. Wenn ja, dann wird die Bedingung wahr. (A <B) ist wahr.
> = Überprüft, ob der Wert des linken Operanden größer oder gleich dem Wert des rechten Operanden ist. Wenn ja, dann wird die Bedingung wahr. (A> = B) ist nicht wahr.
<= Überprüft, ob der Wert des linken Operanden kleiner oder gleich dem Wert des rechten Operanden ist. Wenn ja, dann wird die Bedingung wahr. (A <= B) ist wahr.

Logische Operatoren

Die folgende Tabelle zeigt alle logischen Operatoren, die von der Objective-C-Sprache unterstützt werden. Variable annehmenA hält 1 und variabel B hält 0, dann -

Beispiele anzeigen

Operator Beschreibung Beispiel
&& Wird als logischer UND-Operator bezeichnet. Wenn beide Operanden nicht Null sind, wird die Bedingung wahr. (A && B) ist falsch.
|| Wird als logischer ODER-Operator bezeichnet. Wenn einer der beiden Operanden nicht Null ist, wird die Bedingung wahr. (A || B) ist wahr.
! Wird als logischer NICHT-Operator bezeichnet. Verwenden Sie diese Option, um den logischen Status des Operanden umzukehren. Wenn eine Bedingung wahr ist, macht der Operator Logical NOT false. ! (A && B) ist wahr.

Bitweise Operatoren

Der bitweise Operator bearbeitet Bits und führt eine bitweise Operation durch. Die Wahrheitstabellen für &, | und ^ lauten wie folgt:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Angenommen, A = 60; und B = 13; jetzt im Binärformat werden sie wie folgt sein -

A = 0011 1100

B = 0000 1101

-----------------

A & B = 0000 1100

A | B = 0011 1101

A ^ B = 0011 0001

~ A = 1100 0011

Die von der Objective-C-Sprache unterstützten bitweisen Operatoren sind in der folgenden Tabelle aufgeführt. Angenommen, Variable A hält 60 und Variable B hält 13, dann -

Beispiele anzeigen

Operator Beschreibung Beispiel
& Der binäre UND-Operator kopiert ein Bit in das Ergebnis, wenn es in beiden Operanden vorhanden ist. (A & B) ergibt 12, was 0000 1100 ist
| Der binäre ODER-Operator kopiert ein Bit, wenn es in einem der Operanden vorhanden ist. (A | B) ergibt 61, was 0011 1101 ist
^ Der binäre XOR-Operator kopiert das Bit, wenn es in einem Operanden gesetzt ist, aber nicht in beiden. (A ^ B) ergibt 49, was 0011 0001 ist
~ Der Komplementoperator für binäre Einsen ist unär und bewirkt das Umdrehen von Bits. (~ A) ergibt -61, was 1100 0011 in der 2er-Komplementform ist.
<< Binärer Linksschaltoperator. Der Wert der linken Operanden wird um die Anzahl der vom rechten Operanden angegebenen Bits nach links verschoben. Ein << 2 ergibt 240, was 1111 0000 ist
>> Binärer Rechtsschieber. Der Wert der linken Operanden wird um die Anzahl der vom rechten Operanden angegebenen Bits nach rechts verschoben. Eine >> 2 ergibt 15, was 0000 1111 ist

Zuweisungsoperatoren

Es gibt folgende Zuweisungsoperatoren, die von der Objective-C-Sprache unterstützt werden:

Beispiele anzeigen

Operator Beschreibung Beispiel
= Einfacher Zuweisungsoperator, Weist Werte von Operanden auf der rechten Seite dem Operanden auf der linken Seite zu C = A + B weist C den Wert von A + B zu
+ = UND-Zuweisungsoperator hinzufügen. Er fügt dem linken Operanden den rechten Operanden hinzu und weist das Ergebnis dem linken Operanden zu C + = A entspricht C = C + A.
- = Subtrahieren UND Zuweisungsoperator, subtrahiert den rechten Operanden vom linken Operanden und weist das Ergebnis dem linken Operanden zu C - = A entspricht C = C - A.
* = Multiplizieren Sie den UND-Zuweisungsoperator. Er multipliziert den rechten Operanden mit dem linken Operanden und weist das Ergebnis dem linken Operanden zu C * = A entspricht C = C * A.
/ = Divisions- UND Zuweisungsoperator. Er teilt den linken Operanden mit dem rechten Operanden und weist das Ergebnis dem linken Operanden zu C / = A entspricht C = C / A.
% = Modul- UND Zuweisungsoperator. Der Modul wird mit zwei Operanden verwendet und das Ergebnis dem linken Operanden zugewiesen C% = A entspricht C = C% A.
<< = Linksverschiebung UND Zuweisungsoperator C << = 2 ist dasselbe wie C = C << 2
>> = Rechtsverschiebung UND Zuweisungsoperator C >> = 2 ist dasselbe wie C = C >> 2
& = Bitweiser UND-Zuweisungsoperator C & = 2 ist dasselbe wie C = C & 2
^ = bitweises exklusives ODER und Zuweisungsoperator C ^ = 2 ist dasselbe wie C = C ^ 2
| = bitweises Inklusiv-ODER und Zuweisungsoperator C | = 2 ist dasselbe wie C = C | 2

Verschiedene Operatoren ↦ sizeof & ternary

Es gibt nur wenige andere wichtige Betreiber, einschließlich sizeof und ? : unterstützt von Objective-C Language.

Beispiele anzeigen

Operator Beschreibung Beispiel
Größe von() Gibt die Größe einer Variablen zurück. sizeof (a), wobei a eine ganze Zahl ist, gibt 4 zurück.
& Gibt die Adresse einer Variablen zurück. &ein; gibt die tatsächliche Adresse der Variablen an.
* * Zeiger auf eine Variable. *ein; zeigt auf eine Variable.
? :: Bedingter Ausdruck Wenn Bedingung wahr ist? Dann Wert X: Andernfalls Wert Y.

Vorrang der Operatoren in Ziel-C

Die Operatorrangfolge bestimmt die Gruppierung von Begriffen in einem Ausdruck. Dies wirkt sich darauf aus, wie ein Ausdruck ausgewertet wird. Bestimmte Operatoren haben eine höhere Priorität als andere. Beispielsweise hat der Multiplikationsoperator eine höhere Priorität als der Additionsoperator -

Zum Beispiel ist x = 7 + 3 * 2; Hier wird x 13 zugewiesen, nicht 20, da der Operator * eine höhere Priorität als + hat. Daher wird er zuerst mit 3 * 2 multipliziert und dann zu 7 addiert.

Hier werden Operatoren mit der höchsten Priorität oben in der Tabelle angezeigt, Operatoren mit der niedrigsten Priorität unten. Innerhalb eines Ausdrucks werden zuerst Operatoren mit höherer Priorität ausgewertet.

Kategorie  Operator  Assoziativität 
Postfix  () [] ->. ++ - -   Links nach rechts 
Einstellig  + -! ~ ++ - - (Typ) * & sizeof  Rechts nach links 
Multiplikativ   * /%  Links nach rechts 
Zusatzstoff   + -  Links nach rechts 
Verschiebung   << >>  Links nach rechts 
Relational   << = >> =  Links nach rechts 
Gleichberechtigung   ==! =  Links nach rechts 
Bitweises XOR  Links nach rechts 
Bitweises ODER  Links nach rechts 
Logisches UND  &&  Links nach rechts 
Logisches ODER  ||  Links nach rechts 
Bedingt  ?:  Rechts nach links 
Zuordnung  = + = - = * = / =% = >> = << = & = ^ = | =  Rechts nach links 
Komma  Links nach rechts 

Es kann vorkommen, dass Sie einen Codeblock mehrmals ausführen müssen. Im Allgemeinen werden Anweisungen nacheinander ausgeführt: Die erste Anweisung in einer Funktion wird zuerst ausgeführt, gefolgt von der zweiten usw.

Programmiersprachen bieten verschiedene Steuerungsstrukturen, die kompliziertere Ausführungspfade ermöglichen.

Mit einer Schleifenanweisung können wir eine Anweisung oder eine Gruppe von Anweisungen mehrmals ausführen. Im Folgenden wird die allgemeine Form einer Schleifenanweisung in den meisten Programmiersprachen beschrieben:

Die Programmiersprache Objective-C bietet die folgenden Arten von Schleifen, um die Schleifenanforderungen zu erfüllen. Klicken Sie auf die folgenden Links, um deren Details zu überprüfen.

Sr.Nr. Schleifentyp & Beschreibung
1 while-Schleife

Wiederholt eine Anweisung oder eine Gruppe von Anweisungen, während eine bestimmte Bedingung erfüllt ist. Es testet die Bedingung, bevor der Schleifenkörper ausgeführt wird.

2 für Schleife

Führen Sie eine Folge von Anweisungen mehrmals aus und kürzen Sie den Code ab, der die Schleifenvariable verwaltet.

3 do ... while-Schleife

Wie eine while-Anweisung, nur dass sie die Bedingung am Ende des Schleifenkörpers testet.

4 verschachtelte Schleifen

Sie können eine oder mehrere Schleifen in einer anderen while-, for- oder do..while-Schleife verwenden.

Schleifensteuerungsanweisungen

Schleifensteueranweisungen ändern die Ausführung von ihrer normalen Reihenfolge. Wenn die Ausführung einen Bereich verlässt, werden alle automatischen Objekte, die in diesem Bereich erstellt wurden, zerstört.

Objective-C unterstützt die folgenden Steueranweisungen. Klicken Sie auf die folgenden Links, um deren Details zu überprüfen.

Sr.Nr. Steueranweisung & Beschreibung
1 break-Anweisung

Beendet die loop oder switch Anweisung und überträgt die Ausführung an die Anweisung unmittelbar nach der Schleife oder dem Schalter.

2 Aussage fortsetzen

Bewirkt, dass die Schleife den Rest ihres Körpers überspringt und ihren Zustand sofort erneut testet, bevor sie wiederholt wird.

Die Endlosschleife

Eine Schleife wird zur Endlosschleife, wenn eine Bedingung niemals falsch wird. DasforZu diesem Zweck wird traditionell eine Schleife verwendet. Da keiner der drei Ausdrücke, die die for-Schleife bilden, erforderlich ist, können Sie eine Endlosschleife erstellen, indem Sie den bedingten Ausdruck leer lassen.

#import <Foundation/Foundation.h>
 
int main () {

   for( ; ; ) {
      NSLog(@"This loop will run forever.\n");
   }

   return 0;
}

Wenn der bedingte Ausdruck fehlt, wird angenommen, dass er wahr ist. Möglicherweise haben Sie einen Initialisierungs- und Inkrementausdruck, aber Objective-C-Programmierer verwenden häufiger das for (;;) - Konstrukt, um eine Endlosschleife zu kennzeichnen.

Entscheidungsstrukturen erfordern, dass der Programmierer eine oder mehrere Bedingungen angibt, die vom Programm bewertet oder getestet werden sollen, zusammen mit einer Anweisung oder Anweisungen, die ausgeführt werden sollen, wenn die Bedingung als wahr bestimmt wird, und optional anderen Anweisungen, die ausgeführt werden sollen, wenn die Bedingung ausgeführt wird wird als falsch bestimmt.

Es folgt die allgemeine Form einer typischen Entscheidungsstruktur, die in den meisten Programmiersprachen zu finden ist:

Die Programmiersprache Objective-C setzt alle voraus non-zero und non-null Werte als trueund wenn ja zero oder nulldann wird angenommen als false Wert.

Die Programmiersprache Objective-C bietet die folgenden Arten von Entscheidungsaussagen. Klicken Sie auf die folgenden Links, um deren Details zu überprüfen -

Sr.Nr. Aussage & Beschreibung
1 if-Anweisung

Ein if statement besteht aus einem booleschen Ausdruck, gefolgt von einer oder mehreren Anweisungen.

2 if ... else-Anweisung

Ein if statement kann von einem optionalen gefolgt werden else statement, wird ausgeführt, wenn der boolesche Ausdruck false ist.

3 verschachtelte if-Anweisungen

Sie können eine verwenden if oder else if Aussage in einem anderen if oder else if Aussage (n).

4 switch-Anweisung

EIN switch Mit der Anweisung kann eine Variable auf Gleichheit mit einer Liste von Werten getestet werden.

5 verschachtelte switch-Anweisungen

Sie können eine verwenden switch Aussage in einem anderen switch Aussage (n).

Das ? : Operator

Wir haben abgedeckt conditional operator ? : im vorherigen Kapitel, das zum Ersetzen verwendet werden kann if...elseAussagen. Es hat die folgende allgemeine Form -

Exp1 ? Exp2 : Exp3;

Wobei Exp1, Exp2 und Exp3 Ausdrücke sind. Beachten Sie die Verwendung und Platzierung des Doppelpunkts.

Der Wert eines? Der Ausdruck wird wie folgt bestimmt: Exp1 wird ausgewertet. Wenn es wahr ist, wird Exp2 ausgewertet und wird zum Wert des gesamten? Ausdruck. Wenn Exp1 falsch ist, wird Exp3 ausgewertet und sein Wert wird zum Wert des Ausdrucks.

Eine Funktion ist eine Gruppe von Anweisungen, die zusammen eine Aufgabe ausführen. Jedes Objective-C-Programm hat eine C-Funktionmain()und alle trivialsten Programme können zusätzliche Funktionen definieren.

Sie können Ihren Code in separate Funktionen aufteilen. Wie Sie Ihren Code auf verschiedene Funktionen aufteilen, liegt bei Ihnen. Logischerweise erfolgt die Aufteilung jedoch normalerweise so, dass jede Funktion eine bestimmte Aufgabe ausführt.

Eine Funktion declarationinformiert den Compiler über den Namen, den Rückgabetyp und die Parameter einer Funktion. Eine Funktiondefinition liefert den eigentlichen Körper der Funktion.

Grundsätzlich nennen wir in Objective-C die Funktion als Methode.

Das Objective-C Foundation Framework bietet zahlreiche integrierte Methoden, die Ihr Programm aufrufen kann. Zum Beispiel MethodeappendString() Zeichenfolge an eine andere Zeichenfolge anhängen.

Eine Methode ist mit verschiedenen Namen wie einer Funktion oder einer Unterroutine oder einer Prozedur usw. bekannt.

Defining a Method

The general form of a method definition in Objective-C programming language is as follows −

- (return_type) method_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen {
   body of the function
}

A method definition in Objective-C programming language consists of a method header and a method body. Here are all the parts of a method −

  • Return Type − A method may return a value. The return_type is the data type of the value the function returns. Some methods perform the desired operations without returning a value. In this case, the return_type is the keyword void.

  • Method Name − This is the actual name of the method. The method name and the parameter list together constitute the method signature.

  • Arguments − A argument is like a placeholder. When a function is invoked, you pass a value to the argument. This value is referred to as actual parameter or argument. The parameter list refers to the type, order, and number of the arguments of a method. Arguments are optional; that is, a method may contain no argument.

  • Joining Argument − A joining argument is to make it easier to read and to make it clear while calling it.

  • Method Body − The method body contains a collection of statements that define what the method does.

Beispiel

Es folgt der Quellcode für eine aufgerufene Methode max(). Diese Methode verwendet zwei Parameter num1 und num2 und gibt das Maximum zwischen den beiden zurück -

/* function returning the max between two numbers */
- (int) max:(int) num1 secondNumber:(int) num2 {
   
   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

Methodenerklärungen

Eine Methode declarationinformiert den Compiler über einen Funktionsnamen und den Aufruf der Methode. Der eigentliche Funktionskörper kann separat definiert werden.

Eine Methodendeklaration besteht aus folgenden Teilen:

- (return_type) function_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen;

Für die oben definierte Funktion max () folgt die Methodendeklaration -

-(int) max:(int)num1 andNum2:(int)num2;

Eine Methodendeklaration ist erforderlich, wenn Sie eine Methode in einer Quelldatei definieren und diese Methode in einer anderen Datei aufrufen. In diesem Fall sollten Sie die Funktion oben in der Datei deklarieren, die die Funktion aufruft.

Eine Methode aufrufen

Beim Erstellen einer Objective-C-Methode definieren Sie, was die Funktion zu tun hat. Um eine Methode zu verwenden, müssen Sie diese Funktion aufrufen, um die definierte Aufgabe auszuführen.

Wenn ein Programm eine Funktion aufruft, wird die Programmsteuerung an die aufgerufene Methode übertragen. Eine aufgerufene Methode führt eine definierte Aufgabe aus, und wenn ihre return-Anweisung ausgeführt wird oder wenn ihre schließende Klammer zum Ende der Funktion erreicht ist, gibt sie die Programmsteuerung an das Hauptprogramm zurück.

Um eine Methode aufzurufen, müssen Sie lediglich die erforderlichen Parameter zusammen mit dem Methodennamen übergeben. Wenn die Methode einen Wert zurückgibt, können Sie den zurückgegebenen Wert speichern. Zum Beispiel -

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
/* method declaration */
- (int)max:(int)num1 andNum2:(int)num2;
@end

@implementation SampleClass

/* method returning the max between two numbers */
- (int)max:(int)num1 andNum2:(int)num2 {

   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

@end

int main () {
   
   /* local variable definition */
   int a = 100;
   int b = 200;
   int ret;
   
   SampleClass *sampleClass = [[SampleClass alloc]init];

   /* calling a method to get max value */
   ret = [sampleClass max:a andNum2:b];
 
   NSLog(@"Max value is : %d\n", ret );
   return 0;
}

Ich habe die Funktion max () zusammen mit der Funktion main () beibehalten und den Quellcode eingehalten. Beim Ausführen der endgültigen ausführbaren Datei wird das folgende Ergebnis erzielt:

2013-09-07 22:28:45.912 demo[26080] Max value is : 200

Funktionsargumente

Wenn eine Funktion Argumente verwenden soll, muss sie Variablen deklarieren, die die Werte der Argumente akzeptieren. Diese Variablen werden als bezeichnetformal parameters der Funktion.

Die formalen Parameter verhalten sich wie andere lokale Variablen innerhalb der Funktion und werden beim Eintritt in die Funktion erstellt und beim Beenden zerstört.

Beim Aufrufen einer Funktion gibt es zwei Möglichkeiten, wie Argumente an eine Funktion übergeben werden können:

Sr.Nr. Anruftyp & Beschreibung
1 Call by value

Diese Methode kopiert den tatsächlichen Wert eines Arguments in den formalen Parameter der Funktion. In diesem Fall haben Änderungen am Parameter innerhalb der Funktion keine Auswirkung auf das Argument.

2 Rufen Sie als Referenz an

Diese Methode kopiert die Adresse eines Arguments in den formalen Parameter. Innerhalb der Funktion wird die Adresse verwendet, um auf das tatsächliche Argument zuzugreifen, das im Aufruf verwendet wird. Dies bedeutet, dass Änderungen am Parameter das Argument beeinflussen.

Standardmäßig verwendet Objective-C call by valueArgumente übergeben. Im Allgemeinen bedeutet dies, dass Code innerhalb einer Funktion die zum Aufrufen der Funktion verwendeten Argumente nicht ändern kann. Das oben erwähnte Beispiel beim Aufrufen der Funktion max () verwendete dieselbe Methode.

Eine Objective-C-Klasse definiert ein Objekt, das Daten mit verwandtem Verhalten kombiniert. Manchmal ist es sinnvoll, nur eine einzelne Aufgabe oder Verhaltenseinheit darzustellen und nicht eine Sammlung von Methoden.

Blöcke sind eine Funktion auf Sprachebene, die zu C, Objective-C und C ++ hinzugefügt wurde. Mit dieser Funktion können Sie unterschiedliche Codesegmente erstellen, die an Methoden oder Funktionen weitergegeben werden können, als wären sie Werte. Blöcke sind Objective-C-Objekte, dh sie können Sammlungen wie NSArray oder NSDictionary hinzugefügt werden. Sie können auch Werte aus dem umschließenden Bereich erfassen, wodurch sie Verschlüssen oder Lambdas in anderen Programmiersprachen ähneln

Einfache Blockdeklarationssyntax

returntype (^blockName)(argumentType);

Einfache Blockimplementierung

returntype (^blockName)(argumentType)= ^{
};

Hier ist ein einfaches Beispiel

void (^simpleBlock)(void) = ^{
   NSLog(@"This is a block");
};

Wir können den Block mit aufrufen

simpleBlock();

Blöcke nehmen Argumente an und geben Werte zurück

Blöcke können ebenso wie Methoden und Funktionen Argumente annehmen und Werte zurückgeben.

Hier ist ein einfaches Beispiel zum Implementieren und Aufrufen eines Blocks mit Argumenten und Rückgabewerten.

double (^multiplyTwoValues)(double, double) = 
   ^(double firstValue, double secondValue) {
      return firstValue * secondValue;
   };

double result = multiplyTwoValues(2,4); 
NSLog(@"The result is %f", result);

Blöcke mit Typdefinitionen

Hier ist ein einfaches Beispiel für die Verwendung von typedef im Block. Bitte beachten Sie dieses Beispieldoesn't work auf der online compilerzur Zeit. VerwendenXCode das gleiche laufen lassen.

#import <Foundation/Foundation.h>

typedef void (^CompletionBlock)();
@interface SampleClass:NSObject
- (void)performActionWithCompletion:(CompletionBlock)completionBlock;
@end

@implementation SampleClass

- (void)performActionWithCompletion:(CompletionBlock)completionBlock {

   NSLog(@"Action Performed");
   completionBlock();
}

@end

int main() {
   
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass performActionWithCompletion:^{
      NSLog(@"Completion is called to intimate action is performed.");
   }];

   return 0;
}

Lassen Sie uns es kompilieren und ausführen, es wird das folgende Ergebnis erzeugen -

2013-09-10 08:13:57.155 demo[284:303] Action Performed
2013-09-10 08:13:57.157 demo[284:303] Completion is called to intimate action is performed.

Blöcke werden häufiger in iOS-Anwendungen und Mac OS X verwendet. Daher ist es wichtiger, die Verwendung von Blöcken zu verstehen.

In der Programmiersprache Objective-C, um die grundlegenden Datentypen wie int, float, bool in Objektform zu speichern,

Objective-C bietet eine Reihe von Methoden für die Arbeit mit NSNumber. Wichtige Methoden sind in der folgenden Tabelle aufgeführt.

Sr.Nr. Methode & Beschreibung
1

+ (NSNumber *)numberWithBool:(BOOL)value

Erstellt ein NSNumber-Objekt mit einem bestimmten Wert und gibt es als BOOL zurück.

2

+ (NSNumber *)numberWithChar:(char)value

Erstellt ein NSNumber-Objekt, das einen bestimmten Wert enthält, und gibt es als signiertes Zeichen zurück.

3

+ (NSNumber *)numberWithDouble:(double)value

Erstellt ein NSNumber-Objekt, das einen bestimmten Wert enthält, und gibt es als Double zurück.

4

+ (NSNumber *)numberWithFloat:(float)value

Erstellt und gibt ein NSNumber-Objekt zurück, das einen bestimmten Wert enthält, und behandelt es als Float.

5

+ (NSNumber *)numberWithInt:(int)value

Erstellt ein NSNumber-Objekt mit einem bestimmten Wert und gibt es als signiertes int zurück.

6

+ (NSNumber *)numberWithInteger:(NSInteger)value

Erstellt ein NSNumber-Objekt mit einem bestimmten Wert und gibt es als NSInteger zurück.

7

- (BOOL)boolValue

Gibt den Wert des Empfängers als BOOL zurück.

8

- (char)charValue

Gibt den Wert des Empfängers als Zeichen zurück.

9

- (double)doubleValue

Gibt den Wert des Empfängers als Double zurück.

10

- (float)floatValue

Gibt den Wert des Empfängers als Float zurück.

11

- (NSInteger)integerValue

Gibt den Wert des Empfängers als NSInteger zurück.

12

- (int)intValue

Gibt den Wert des Empfängers als int zurück.

13

- (NSString *)stringValue

Gibt den Wert des Empfängers als lesbare Zeichenfolge zurück.

Hier ist ein einfaches Beispiel für die Verwendung von NSNumber, das zwei Zahlen multipliziert und das Produkt zurückgibt.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b;
@end

@implementation SampleClass

- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b {
   float number1 = [a floatValue];
   float number2 = [b floatValue];
   float product = number1 * number2;
   NSNumber *result = [NSNumber numberWithFloat:product];
   return result;
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   SampleClass *sampleClass = [[SampleClass alloc]init];
   NSNumber *a = [NSNumber numberWithFloat:10.5];
   NSNumber *b = [NSNumber numberWithFloat:10.0];   
   NSNumber *result = [sampleClass multiplyA:a withB:b];
   NSString *resultString = [result stringValue];
   NSLog(@"The product is %@",resultString);

   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-14 18:53:40.575 demo[16787] The product is 105

Die Programmiersprache Objective-C bietet eine Datenstruktur namens the array, die eine sequentielle Sammlung von Elementen desselben Typs mit fester Größe speichern kann. Ein Array wird zum Speichern einer Sammlung von Daten verwendet. Oft ist es jedoch sinnvoller, sich ein Array als eine Sammlung von Variablen desselben Typs vorzustellen.

Anstatt einzelne Variablen wie Nummer 0, Nummer 1, ... und Nummer 99 zu deklarieren, deklarieren Sie eine Array-Variable wie Zahlen und verwenden Zahlen [0], Zahlen [1] und ..., Zahlen [99] zur Darstellung einzelne Variablen. Auf ein bestimmtes Element in einem Array wird über einen Index zugegriffen.

Alle Arrays bestehen aus zusammenhängenden Speicherstellen. Die niedrigste Adresse entspricht dem ersten Element und die höchste Adresse dem letzten Element.

Arrays deklarieren

Um ein Array in Objective-C zu deklarieren, gibt ein Programmierer den Typ der Elemente und die Anzahl der für ein Array erforderlichen Elemente wie folgt an:

type arrayName [ arraySize ];

Dies wird als eindimensionales Array bezeichnet. DasarraySize muss eine ganzzahlige Konstante größer als Null sein und typekann ein beliebiger gültiger Objective-C-Datentyp sein. Zum Beispiel, um ein Array mit 10 Elementen zu deklarieren, das aufgerufen wirdbalance Verwenden Sie diese Anweisung vom Typ double -

double balance[10];

Nun Balance ist eine variable Anordnung, die bis zu 10 Doppel Zahlen zu halten ausreichend ist.

Arrays initialisieren

Sie können ein Array in Objective-C entweder einzeln oder mithilfe einer einzelnen Anweisung wie folgt initialisieren:

double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};

Die Anzahl der Werte zwischen geschweiften Klammern {} darf nicht größer sein als die Anzahl der Elemente, die wir für das Array zwischen eckigen Klammern [] deklarieren. Es folgt ein Beispiel zum Zuweisen eines einzelnen Elements des Arrays:

Wenn Sie die Größe des Arrays weglassen, wird ein Array erstellt, das gerade groß genug ist, um die Initialisierung aufzunehmen. Deshalb, wenn Sie schreiben -

double balance[] = {1000.0, 2.0, 3.4, 17.0, 50.0};

Sie erstellen genau das gleiche Array wie im vorherigen Beispiel.

balance[4] = 50.0;

Die obige Anweisung weist dem Element Nummer 5 im Array einen Wert von 50,0 zu. Array mit dem 4. Index ist das 5., dh das letzte Element, da alle Arrays 0 als Index ihres ersten Elements haben, das auch als Basisindex bezeichnet wird. Es folgt die bildliche Darstellung des gleichen Arrays, das wir oben besprochen haben -

Zugriff auf Array-Elemente

Auf ein Element wird zugegriffen, indem der Arrayname indiziert wird. Dazu wird der Index des Elements in eckige Klammern nach dem Namen des Arrays gesetzt. Zum Beispiel -

double salary = balance[9];

Die obige Anweisung nimmt das 10. Element aus dem Array und weist den Wert der Gehaltsvariablen zu. Es folgt ein Beispiel, in dem alle oben genannten drei Konzepte verwendet werden. Deklaration, Zuweisung und Zugriff auf Arrays -

#import <Foundation/Foundation.h>
 
int main () {
   int n[ 10 ];   /* n is an array of 10 integers */
   int i,j;
 
   /* initialize elements of array n to 0 */         
   for ( i = 0; i < 10; i++ ) {
      n[ i ] = i + 100;    /* set element at location i to i + 100 */
   }
   
   /* output each array element's value */
   for (j = 0; j < 10; j++ ) {
      NSLog(@"Element[%d] = %d\n", j, n[j] );
   }
 
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 01:24:06.669 demo[16508] Element[0] = 100
2013-09-14 01:24:06.669 demo[16508] Element[1] = 101
2013-09-14 01:24:06.669 demo[16508] Element[2] = 102
2013-09-14 01:24:06.669 demo[16508] Element[3] = 103
2013-09-14 01:24:06.669 demo[16508] Element[4] = 104
2013-09-14 01:24:06.669 demo[16508] Element[5] = 105
2013-09-14 01:24:06.669 demo[16508] Element[6] = 106
2013-09-14 01:24:06.669 demo[16508] Element[7] = 107
2013-09-14 01:24:06.669 demo[16508] Element[8] = 108
2013-09-14 01:24:06.669 demo[16508] Element[9] = 109

Objective-C-Arrays im Detail

Arrays sind für Objective-C wichtig und benötigen viele weitere Details. Es gibt einige wichtige Konzepte im Zusammenhang mit Arrays, die einem Objective-C-Programmierer klar sein sollten:

Sr.Nr. Konzept & Beschreibung
1 Mehrdimensionale Arrays

Objective-C unterstützt mehrdimensionale Arrays. Die einfachste Form des mehrdimensionalen Arrays ist das zweidimensionale Array.

2 Übergeben von Arrays an Funktionen

Sie können der Funktion einen Zeiger auf ein Array übergeben, indem Sie den Namen des Arrays ohne Index angeben.

3 Array von einer Funktion zurückgeben

Mit Objective-C kann eine Funktion ein Array zurückgeben.

4 Zeiger auf ein Array

Sie können einen Zeiger auf das erste Element eines Arrays generieren, indem Sie einfach den Arraynamen ohne Index angeben.

Zeiger in Objective-C sind einfach und machen Spaß zu lernen. Einige Objective-C-Programmieraufgaben lassen sich einfacher mit Zeigern ausführen, und andere Aufgaben, z. B. die dynamische Speicherzuweisung, können nicht ohne Verwendung von Zeigern ausgeführt werden. Es wird also notwendig, Zeiger zu lernen, um ein perfekter Objective-C-Programmierer zu werden. Beginnen wir damit, sie in einfachen Schritten zu lernen.

Wie Sie wissen, ist jede Variable ein Speicherort, und für jeden Speicherort ist eine Adresse definiert, auf die mit dem kaufmännischen Und (&) -Operator zugegriffen werden kann, der eine Adresse im Speicher angibt. Betrachten Sie das folgende Beispiel, in dem die Adresse der definierten Variablen gedruckt wird:

#import <Foundation/Foundation.h>

int main () {
   int  var1;
   char var2[10];

   NSLog(@"Address of var1 variable: %x\n", &var1 );
   NSLog(@"Address of var2 variable: %x\n", &var2 );

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das Ergebnis wie folgt:

2013-09-13 03:18:45.727 demo[17552] Address of var1 variable: 1c0843fc
2013-09-13 03:18:45.728 demo[17552] Address of var2 variable: 1c0843f0

Sie haben also verstanden, was Speicheradresse ist und wie Sie darauf zugreifen können. Die Basis des Konzepts ist also vorbei. Lassen Sie uns nun sehen, was ein Zeiger ist.

Was sind Zeiger?

EIN pointerist eine Variable, deren Wert die Adresse einer anderen Variablen ist, dh die direkte Adresse des Speicherorts. Wie bei jeder Variablen oder Konstante müssen Sie einen Zeiger deklarieren, bevor Sie ihn zum Speichern einer Variablenadresse verwenden können. Die allgemeine Form einer Zeigervariablendeklaration lautet -

type *var-name;

Hier, typeist der Basistyp des Zeigers; Es muss ein gültiger Objective-C-Datentyp sein undvar-nameist der Name der Zeigervariable. Das Sternchen *, mit dem Sie einen Zeiger deklariert haben, ist das gleiche Sternchen, das Sie für die Multiplikation verwenden. In dieser Anweisung wird das Sternchen jedoch verwendet, um eine Variable als Zeiger zu kennzeichnen. Es folgen die gültigen Zeigerdeklarationen -

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

Der tatsächliche Datentyp des Werts aller Zeiger, ob Ganzzahl, Gleitkomma, Zeichen oder auf andere Weise, ist derselbe, eine lange Hexadezimalzahl, die eine Speicheradresse darstellt. Der einzige Unterschied zwischen Zeigern verschiedener Datentypen ist der Datentyp der Variablen oder Konstante, auf die der Zeiger zeigt.

Wie benutze ich Zeiger?

Es gibt nur wenige wichtige Operationen, die wir sehr häufig mit Hilfe von Zeigern ausführen werden. (a) wir definieren eine Zeigervariable, (b) Weisen Sie einem Zeiger die Adresse einer Variablen zu, und (c)Greifen Sie schließlich auf den Wert an der Adresse zu, die in der Zeigervariablen verfügbar ist. Dies erfolgt mit einem unären Operator*Dies gibt den Wert der Variablen zurück, die sich an der durch ihren Operanden angegebenen Adresse befindet. Das folgende Beispiel verwendet diese Operationen -

#import <Foundation/Foundation.h>

int main () {
   int  var = 20;    /* actual variable declaration */
   int  *ip;         /* pointer variable declaration */  
   ip = &var;       /* store address of var in pointer variable*/

   NSLog(@"Address of var variable: %x\n", &var  );

   /* address stored in pointer variable */
   NSLog(@"Address stored in ip variable: %x\n", ip );

   /* access the value using the pointer */
   NSLog(@"Value of *ip variable: %d\n", *ip );

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das Ergebnis wie folgt:

2013-09-13 03:20:21.873 demo[24179] Address of var variable: 337ed41c
2013-09-13 03:20:21.873 demo[24179] Address stored in ip variable: 337ed41c
2013-09-13 03:20:21.874 demo[24179] Value of *ip variable: 20

NULL-Zeiger in Ziel-C

Es wird immer empfohlen, einer Zeigervariablen einen NULL-Wert zuzuweisen, falls Ihnen keine genaue Adresse zugewiesen werden muss. Dies erfolgt zum Zeitpunkt der Variablendeklaration. Ein Zeiger, dem NULL zugewiesen ist, heißt anull Zeiger.

Der NULL-Zeiger ist eine Konstante mit dem Wert Null, die in mehreren Standardbibliotheken definiert ist. Betrachten Sie das folgende Programm -

#import <Foundation/Foundation.h>

int main () {
   int  *ptr = NULL;
   NSLog(@"The value of ptr is : %x\n", ptr  );
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-13 03:21:19.447 demo[28027] The value of ptr is : 0

Auf den meisten Betriebssystemen dürfen Programme unter der Adresse 0 nicht auf den Speicher zugreifen, da dieser Speicher vom Betriebssystem reserviert wird. Die Speicheradresse 0 hat jedoch eine besondere Bedeutung; es signalisiert, dass der Zeiger nicht auf einen zugänglichen Speicherort zeigen soll. Wenn ein Zeiger jedoch den Wert Null (Null) enthält, wird angenommen, dass er auf nichts zeigt.

Um nach einem Nullzeiger zu suchen, können Sie eine if-Anweisung wie folgt verwenden:

if(ptr)     /* succeeds if p is not null */
if(!ptr)    /* succeeds if p is null */

Ziel-C-Zeiger im Detail

Zeiger haben viele, aber einfache Konzepte und sind für die Objective-C-Programmierung sehr wichtig. Es gibt einige wichtige Zeigerkonzepte, die einem Objective-C-Programmierer klar sein sollten:

Sr.Nr. Konzept & Beschreibung
1 Ziel-C - Zeigerarithmetik

Es gibt vier arithmetische Operatoren, die für Zeiger verwendet werden können: ++, -, +, -

2 Objective-C - Array von Zeigern

Sie können Arrays definieren, die eine Reihe von Zeigern enthalten.

3 Ziel-C - Zeiger auf Zeiger

Mit Objective-C können Sie einen Zeiger auf einen Zeiger usw. setzen.

4 Übergeben von Zeigern an Funktionen in Objective-C

Durch Übergeben eines Arguments als Referenz oder als Adresse kann das übergebene Argument in der aufrufenden Funktion von der aufgerufenen Funktion geändert werden.

5 Zeiger von Funktionen in Objective-C zurückgeben

Mit Objective-C kann eine Funktion einen Zeiger auf eine lokale Variable, eine statische Variable und einen dynamisch zugewiesenen Speicher zurückgeben.

Die Zeichenfolge in der Programmiersprache Objective-C wird mit NSString dargestellt, und ihre Unterklasse NSMutableString bietet verschiedene Möglichkeiten zum Erstellen von Zeichenfolgenobjekten. Der einfachste Weg, ein String-Objekt zu erstellen, ist die Verwendung des Objective-C @ "..." - Konstrukts -

NSString *greeting = @"Hello";

Ein einfaches Beispiel zum Erstellen und Drucken einer Zeichenfolge ist unten dargestellt.

#import <Foundation/Foundation.h>

int main () {
   NSString *greeting = @"Hello";
   NSLog(@"Greeting message: %@\n", greeting );

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt er Folgendes:

2013-09-11 01:21:39.922 demo[23926] Greeting message: Hello

Objective-C unterstützt eine Vielzahl von Methoden zum Bearbeiten von Zeichenfolgen -

Sr.Nr. Methode & Zweck
1

- (NSString *)capitalizedString;

Gibt eine großgeschriebene Darstellung des Empfängers zurück.

2

- (unichar)characterAtIndex:(NSUInteger)index;

Gibt das Zeichen an einer bestimmten Array-Position zurück.

3

- (double)doubleValue;

Gibt den Gleitkommawert des Empfängertextes als Double zurück.

4

- (float)floatValue;

Gibt den Gleitkommawert des Empfängertextes als Gleitkomma zurück.

5

- (BOOL)hasPrefix:(NSString *)aString;

Gibt einen booleschen Wert zurück, der angibt, ob eine bestimmte Zeichenfolge mit den Anfangszeichen des Empfängers übereinstimmt.

6

- (BOOL)hasSuffix:(NSString *)aString;

Gibt einen booleschen Wert zurück, der angibt, ob eine bestimmte Zeichenfolge mit den Endzeichen des Empfängers übereinstimmt.

7

- (id)initWithFormat:(NSString *)format ...;

Gibt ein NSString-Objekt zurück, das mithilfe einer bestimmten Formatzeichenfolge als Vorlage initialisiert wurde, in die die verbleibenden Argumentwerte eingesetzt werden.

8

- (NSInteger)integerValue;

Gibt den NSInteger-Wert des Empfängertextes zurück.

9

- (BOOL)isEqualToString:(NSString *)aString;

Gibt einen booleschen Wert zurück, der mithilfe eines Literal-Unicode-basierten Vergleichs angibt, ob eine bestimmte Zeichenfolge dem Empfänger entspricht.

10

- (NSUInteger)length;

Gibt die Anzahl der Unicode-Zeichen im Empfänger zurück.

11

- (NSString *)lowercaseString;

Gibt eine Darstellung des Empfängers in Kleinbuchstaben zurück.

12

- (NSRange)rangeOfString:(NSString *)aString;

Findet den Bereich des ersten Auftretens einer bestimmten Zeichenfolge im Empfänger und gibt ihn zurück.

13

- (NSString *)stringByAppendingFormat:(NSString *)format ...;

Gibt eine Zeichenfolge zurück, die durch Anhängen einer Zeichenfolge an den Empfänger erstellt wurde, die aus einer bestimmten Formatzeichenfolge und den folgenden Argumenten erstellt wurde.

14

- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;

Gibt eine neue Zeichenfolge zurück, die durch Entfernen der in einem bestimmten Zeichensatz enthaltenen Empfängerzeichen an beiden Enden erstellt wurde.

15

- (NSString *)substringFromIndex:(NSUInteger)anIndex;

Gibt eine neue Zeichenfolge zurück, die die Zeichen des Empfängers von der Zeichenfolge an einem bestimmten Index bis zum Ende enthält.

Das folgende Beispiel verwendet einige der oben genannten Funktionen -

#import <Foundation/Foundation.h>

int main () {
   NSString *str1 = @"Hello";
   NSString *str2 = @"World";
   NSString *str3;
   int  len ;

   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   /* uppercase string */
   str3 = [str2 uppercaseString];
   NSLog(@"Uppercase String :  %@\n", str3 );

   /* concatenates str1 and str2 */
   str3 = [str1 stringByAppendingFormat:@"World"];
   NSLog(@"Concatenated string:   %@\n", str3 );

   /* total length of str3 after concatenation */
   len = [str3 length];
   NSLog(@"Length of Str3 :  %d\n", len );

   /* InitWithFormat */
   str3 = [[NSString alloc] initWithFormat:@"%@ %@",str1,str2];	
   NSLog(@"Using initWithFormat:   %@\n", str3 );
   [pool drain];

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt er Folgendes:

2013-09-11 01:15:45.069 demo[30378] Uppercase String :  WORLD
2013-09-11 01:15:45.070 demo[30378] Concatenated string:   HelloWorld
2013-09-11 01:15:45.070 demo[30378] Length of Str3 :  10
2013-09-11 01:15:45.070 demo[30378] Using initWithFormat:   Hello World

Eine vollständige Liste der Objective-C NSString-bezogenen Methoden finden Sie in der NSString-Klassenreferenz.

Mit Objective-C-Arrays können Sie Variablentypen definieren, die jedoch mehrere Datenelemente derselben Art enthalten können structure ist ein weiterer benutzerdefinierter Datentyp, der in der Objective-C-Programmierung verfügbar ist und es Ihnen ermöglicht, Datenelemente verschiedener Art zu kombinieren.

Strukturen werden verwendet, um einen Datensatz darzustellen. Angenommen, Sie möchten Ihre Bücher in einer Bibliothek verfolgen. Möglicherweise möchten Sie die folgenden Attribute für jedes Buch verfolgen:

  • Title
  • Author
  • Subject
  • Buch-ID

Struktur definieren

Um eine Struktur zu definieren, müssen Sie die verwenden structErklärung. Die struct-Anweisung definiert einen neuen Datentyp mit mehr als einem Mitglied für Ihr Programm. Das Format der struct-Anweisung lautet:

struct [structure tag] {
   member definition;
   member definition;
   ...
   member definition;
} [one or more structure variables];

Das structure tagist optional und jede Mitgliedsdefinition ist eine normale Variablendefinition, wie z. B. int i; oder float f; oder eine andere gültige Variablendefinition. Am Ende der Strukturdefinition können Sie vor dem letzten Semikolon eine oder mehrere Strukturvariablen angeben, dies ist jedoch optional. Hier ist die Art und Weise, wie Sie die Buchstruktur deklarieren würden:

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
} book;

Zugriff auf Strukturmitglieder

Um auf ein Mitglied einer Struktur zuzugreifen, verwenden wir die member access operator (.). Der Elementzugriffsoperator wird als Punkt zwischen dem Namen der Strukturvariablen und dem Strukturelement codiert, auf das wir zugreifen möchten. Sie würden verwendenstructSchlüsselwort zum Definieren von Variablen des Strukturtyps. Das folgende Beispiel erläutert die Verwendung der Struktur:

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};
 
int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   /* print Book1 info */
   NSLog(@"Book 1 title : %@\n", Book1.title);
   NSLog(@"Book 1 author : %@\n", Book1.author);
   NSLog(@"Book 1 subject : %@\n", Book1.subject);
   NSLog(@"Book 1 book_id : %d\n", Book1.book_id);

   /* print Book2 info */
   NSLog(@"Book 2 title : %@\n", Book2.title);
   NSLog(@"Book 2 author : %@\n", Book2.author);
   NSLog(@"Book 2 subject : %@\n", Book2.subject);
   NSLog(@"Book 2 book_id : %d\n", Book2.book_id);

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 04:20:07.947 demo[20591] Book 1 title : Objective-C Programming
2013-09-14 04:20:07.947 demo[20591] Book 1 author : Nuha Ali
2013-09-14 04:20:07.947 demo[20591] Book 1 subject : Objective-C Programming Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 1 book_id : 6495407
2013-09-14 04:20:07.947 demo[20591] Book 2 title : Telecom Billing
2013-09-14 04:20:07.947 demo[20591] Book 2 author : Zara Ali
2013-09-14 04:20:07.947 demo[20591] Book 2 subject : Telecom Billing Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 2 book_id : 6495700

Strukturen als Funktionsargumente

Sie können eine Struktur als Funktionsargument auf sehr ähnliche Weise übergeben wie jede andere Variable oder jeden anderen Zeiger. Sie würden auf Strukturvariablen auf ähnliche Weise zugreifen wie im obigen Beispiel -

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* function declaration */
- (void) printBook:( struct Books) book ;
@end

@implementation SampleClass 

- (void) printBook:( struct Books) book {
   NSLog(@"Book title : %@\n", book.title);
   NSLog(@"Book author : %@\n", book.author);
   NSLog(@"Book subject : %@\n", book.subject);
   NSLog(@"Book book_id : %d\n", book.book_id);
}

@end

int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info */
   [sampleClass printBook: Book1];

   /* Print Book2 info */
   [sampleClass printBook: Book2];

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 04:34:45.725 demo[8060] Book title : Objective-C Programming
2013-09-14 04:34:45.725 demo[8060] Book author : Nuha Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Objective-C Programming Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495407
2013-09-14 04:34:45.725 demo[8060] Book title : Telecom Billing
2013-09-14 04:34:45.725 demo[8060] Book author : Zara Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Telecom Billing Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495700

Zeiger auf Strukturen

Sie können Zeiger auf Strukturen auf sehr ähnliche Weise definieren, wie Sie Zeiger auf eine andere Variable wie folgt definieren:

struct Books *struct_pointer;

Jetzt können Sie die Adresse einer Strukturvariablen in der oben definierten Zeigervariablen speichern. Um die Adresse einer Strukturvariablen zu ermitteln, platzieren Sie den Operator & wie folgt vor dem Namen der Struktur:

struct_pointer = &Book1;

Um mit einem Zeiger auf diese Struktur auf die Elemente einer Struktur zuzugreifen, müssen Sie den Operator -> wie folgt verwenden:

struct_pointer->title;

Lassen Sie uns das obige Beispiel mit dem Strukturzeiger neu schreiben. Wir hoffen, dass Sie das Konzept leicht verstehen können.

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* function declaration */
- (void) printBook:( struct Books *) book ;
@end

@implementation SampleClass 
- (void) printBook:( struct Books *) book {
   NSLog(@"Book title : %@\n", book->title);
   NSLog(@"Book author : %@\n", book->author);
   NSLog(@"Book subject : %@\n", book->subject);
   NSLog(@"Book book_id : %d\n", book->book_id);
}

@end

int main() {
   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali"; 
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

   /* book 2 specification */
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;
 
   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info by passing address of Book1 */
   [sampleClass printBook:&Book1];

   /* print Book2 info by passing address of Book2 */
   [sampleClass printBook:&Book2];

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 04:38:13.942 demo[20745] Book title : Objective-C Programming
2013-09-14 04:38:13.942 demo[20745] Book author : Nuha Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Objective-C Programming Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495407
2013-09-14 04:38:13.942 demo[20745] Book title : Telecom Billing
2013-09-14 04:38:13.942 demo[20745] Book author : Zara Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Telecom Billing Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495700

Bitfelder

Bitfelder ermöglichen das Packen von Daten in eine Struktur. Dies ist besonders nützlich, wenn der Speicher- oder Datenspeicher knapp ist. Typische Beispiele -

  • Mehrere Objekte in ein Maschinenwort packen. zB 1-Bit-Flags können komprimiert werden.

  • Externe Dateiformate lesen - Nicht standardmäßige Dateiformate können eingelesen werden. ZB 9-Bit-Ganzzahlen.

Mit Objective-C können wir dies in einer Strukturdefinition tun, indem wir: Bitlänge nach der Variablen setzen. Zum Beispiel -

struct packed_struct {
   unsigned int f1:1;
   unsigned int f2:1;
   unsigned int f3:1;
   unsigned int f4:1;
   unsigned int type:4;
   unsigned int my_int:9;
} pack;

Hier enthält das gepackte_Struktur 6 Elemente: Vier 1-Bit-Flags f1..f3, ein 4-Bit-Typ und ein 9-Bit-my_int.

Objective-C packt die obigen Bitfelder automatisch so kompakt wie möglich, vorausgesetzt, die maximale Länge des Feldes ist kleiner oder gleich der ganzzahligen Wortlänge des Computers. Wenn dies nicht der Fall ist, erlauben einige Compiler möglicherweise eine Speicherüberlappung für die Felder, während andere das nächste Feld im nächsten Wort speichern würden.

Das Objective-C Preprocessorist nicht Teil des Compilers, sondern ein separater Schritt im Kompilierungsprozess. Vereinfacht ausgedrückt ist ein Objective-C-Präprozessor nur ein Textersetzungswerkzeug und weist den Compiler an, vor der eigentlichen Kompilierung die erforderliche Vorverarbeitung durchzuführen. Wir werden den Objective-C-Präprozessor als OCPP bezeichnen.

Alle Präprozessorbefehle beginnen mit einem Pfund-Symbol (#). Es muss das erste nicht leere Zeichen sein, und aus Gründen der Lesbarkeit sollte eine Präprozessoranweisung in der ersten Spalte beginnen. Der folgende Abschnitt listet alle wichtigen Präprozessoranweisungen auf -

Sr.Nr. Richtlinie & Beschreibung
1

#define

Ersetzt ein Präprozessor-Makro

2

#include

Fügt einen bestimmten Header aus einer anderen Datei ein

3

#undef

Undefiniert ein Präprozessor-Makro

4

#ifdef

Gibt true zurück, wenn dieses Makro definiert ist

5

#ifndef

Gibt true zurück, wenn dieses Makro nicht definiert ist

6

#if

Testet, ob eine Kompilierungszeitbedingung erfüllt ist

7

#else

Die Alternative für #if

8

#elif

#else ein #if in einer Anweisung

9

#endif

Beendet den Präprozessor unter bestimmten Bedingungen

10

#error

Druckt eine Fehlermeldung auf stderr

11

#pragma

Gibt spezielle Befehle mit einer standardisierten Methode an den Compiler aus

Präprozessor-Beispiele

Analysieren Sie die folgenden Beispiele, um verschiedene Richtlinien zu verstehen.

#define MAX_ARRAY_LENGTH 20

Diese Anweisung weist das OCPP an, Instanzen von MAX_ARRAY_LENGTH durch 20 zu ersetzen. Verwenden Sie #define für Konstanten, um die Lesbarkeit zu verbessern .

#import <Foundation/Foundation.h>
#include "myheader.h"

Diese Anweisungen weisen die OCPP an, die Stiftung.h von zu erhalten Foundation Frameworkund fügen Sie den Text zur aktuellen Quelldatei hinzu. Die nächste Zeile weist OCPP an, abzurufenmyheader.h aus dem lokalen Verzeichnis und fügen Sie den Inhalt der aktuellen Quelldatei hinzu.

#undef  FILE_SIZE
#define FILE_SIZE 42

Dies weist das OCPP an, das vorhandene FILE_SIZE aufzuheben und als 42 zu definieren.

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

Dies weist das OCPP an, MESSAGE nur zu definieren, wenn MESSAGE noch nicht definiert ist.

#ifdef DEBUG
   /* Your debugging statements here */
#endif

Dies weist das OCPP an, den Prozess mit den beiliegenden Anweisungen durchzuführen, wenn DEBUG definiert ist. Dies ist nützlich, wenn Sie das Flag -DDEBUG zum Zeitpunkt der Kompilierung an den gcc-Compiler übergeben. Dadurch wird DEBUG definiert, sodass Sie das Debuggen während der Kompilierung im laufenden Betrieb ein- und ausschalten können.

Vordefinierte Makros

ANSI C definiert eine Reihe von Makros. Obwohl jedes für Ihre Verwendung in der Programmierung verfügbar ist, sollten die vordefinierten Makros nicht direkt geändert werden.

Sr.Nr. Makro & Beschreibung
1

__DATE__

Das aktuelle Datum als Zeichenliteral im Format "MMM TT JJJJ"

2

__TIME__

Die aktuelle Zeit als Zeichenliteral im Format "HH: MM: SS"

3

__FILE__

Dieser enthält den aktuellen Dateinamen als String-Literal.

4

__LINE__

Diese enthält die aktuelle Zeilennummer als Dezimalkonstante.

5

__STDC__

Definiert als 1, wenn der Compiler dem ANSI-Standard entspricht.

Versuchen wir das folgende Beispiel -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"File :%s\n", __FILE__ );
   NSLog(@"Date :%s\n", __DATE__ );
   NSLog(@"Time :%s\n", __TIME__ );
   NSLog(@"Line :%d\n", __LINE__ );
   NSLog(@"ANSI :%d\n", __STDC__ );
   
   return 0;
}

Wenn der obige Code in einer Datei main.m wird kompiliert und ausgeführt, ergibt sich folgendes Ergebnis:

2013-09-14 04:46:14.859 demo[20683] File :main.m
2013-09-14 04:46:14.859 demo[20683] Date :Sep 14 2013
2013-09-14 04:46:14.859 demo[20683] Time :04:46:14
2013-09-14 04:46:14.859 demo[20683] Line :8
2013-09-14 04:46:14.859 demo[20683] ANSI :1

Präprozessor-Operatoren

Der Objective-C-Präprozessor bietet folgende Operatoren, die Sie beim Erstellen von Makros unterstützen:

Makro-Fortsetzung (\)

Ein Makro muss normalerweise in einer einzelnen Zeile enthalten sein. Der Makro-Fortsetzungsoperator wird verwendet, um ein Makro fortzusetzen, das für eine einzelne Zeile zu lang ist. Zum Beispiel -

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

Stringize (#)

Der Stringize- oder Zahlenzeichenoperator ('#') konvertiert bei Verwendung innerhalb einer Makrodefinition einen Makroparameter in eine String-Konstante. Dieser Operator darf nur in einem Makro verwendet werden, für das ein Argument oder eine Parameterliste angegeben ist. Zum Beispiel -

#import <Foundation/Foundation.h>

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

int main(void) {
   message_for(Carole, Debra);
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!

Token einfügen (##)

Der Token-Pasting-Operator (##) in einer Makrodefinition kombiniert zwei Argumente. Damit können zwei separate Token in der Makrodefinition zu einem einzigen Token zusammengefügt werden. Zum Beispiel -

#import <Foundation/Foundation.h>

#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)

int main(void) {
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:48:14.859 demo[20683] token34 = 40

Wie es passiert ist, weil dieses Beispiel zu der folgenden tatsächlichen Ausgabe vom Präprozessor führt -

NSLog (@"token34 = %d", token34);

Dieses Beispiel zeigt die Verkettung von Token ## n zu Token34, und hier haben wir beide verwendet stringize und token-pasting.

Der definierte () Operator

Der Präprozessor definedDer Operator wird in konstanten Ausdrücken verwendet, um zu bestimmen, ob ein Bezeichner mit #define definiert ist. Wenn der angegebene Bezeichner definiert ist, ist der Wert wahr (ungleich Null). Wenn das Symbol nicht definiert ist, ist der Wert falsch (Null). Der definierte Operator wird wie folgt angegeben:

#import <Foundation/Foundation.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void) {
   NSLog(@"Here is the message: %s\n", MESSAGE);  
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!

Parametrisierte Makros

Eine der leistungsstarken Funktionen des OCPP ist die Möglichkeit, Funktionen mithilfe parametrisierter Makros zu simulieren. Zum Beispiel könnten wir einen Code haben, um eine Zahl wie folgt zu quadrieren:

int square(int x) {
   return x * x;
}

Wir können den obigen Code mit einem Makro wie folgt umschreiben:

#define square(x) ((x) * (x))

Makros mit Argumenten müssen mit dem definiert werden #defineRichtlinie, bevor sie verwendet werden können. Die Argumentliste ist in Klammern eingeschlossen und muss unmittelbar auf den Makronamen folgen. Zwischen dem Makronamen und der offenen Klammer sind keine Leerzeichen zulässig. Zum Beispiel -

#import <Foundation/Foundation.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void) {
   NSLog(@"Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20

Die Programmiersprache Objective-C enthält ein Schlüsselwort namens typedef, mit dem Sie einem Typ einen neuen Namen geben können. Im Folgenden finden Sie ein Beispiel zum Definieren eines BegriffsBYTE für Ein-Byte-Nummern -

typedef unsigned char BYTE;

Nach dieser Typdefinition kann der Bezeichner BYTE als Abkürzung für den Typ verwendet werden unsigned char, for example:.

BYTE  b1, b2;

Konventionell werden für diese Definitionen Großbuchstaben verwendet, um den Benutzer daran zu erinnern, dass der Typname tatsächlich eine symbolische Abkürzung ist. Sie können jedoch wie folgt Kleinbuchstaben verwenden:

typedef unsigned char byte;

Sie können verwenden typedefum auch dem benutzerdefinierten Datentyp einen Namen zu geben. Beispielsweise können Sie typedef mit Struktur verwenden, um einen neuen Datentyp zu definieren, und dann diesen Datentyp verwenden, um Strukturvariablen direkt wie folgt zu definieren:

#import <Foundation/Foundation.h>

typedef struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int book_id;
} Book;
 
int main() {
   Book book;
   book.title = @"Objective-C Programming";
   book.author = @"TutorialsPoint";
   book.subject = @"Programming tutorial";
   book.book_id = 100;
   
   NSLog( @"Book title : %@\n", book.title);
   NSLog( @"Book author : %@\n", book.author);
   NSLog( @"Book subject : %@\n", book.subject);
   NSLog( @"Book Id : %d\n", book.book_id);

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-12 12:21:53.745 demo[31183] Book title : Objective-C Programming
2013-09-12 12:21:53.745 demo[31183] Book author : TutorialsPoint
2013-09-12 12:21:53.745 demo[31183] Book subject : Programming tutorial
2013-09-12 12:21:53.745 demo[31183] Book Id : 100

typedef vs #define

Das #define ist eine Objective-C-Direktive, mit der auch die Aliase für verschiedene Datentypen ähnlich wie definiert werden typedef aber mit folgenden Unterschieden -

  • Das typedef beschränkt sich darauf, nur Typen symbolische Namen zu geben, während #define kann auch verwendet werden, um Alias ​​für Werte zu definieren, wie Sie 1 als EINS usw. definieren können.

  • Das typedef Die Interpretation wird vom Compiler durchgeführt, wobei as #define Anweisungen werden vom Vorprozessor verarbeitet.

Das Folgende ist eine einfachste Verwendung von #define -

#import <Foundation/Foundation.h>
 
#define TRUE  1
#define FALSE 0
 
int main( ) {
   NSLog( @"Value of TRUE : %d\n", TRUE);
   NSLog( @"Value of FALSE : %d\n", FALSE);

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-12 12:23:37.993 demo[5160] Value of TRUE : 1
2013-09-12 12:23:37.994 demo[5160] Value of FALSE : 0

Typumwandlung ist eine Möglichkeit, eine Variable von einem Datentyp in einen anderen Datentyp zu konvertieren. Wenn Sie beispielsweise einen langen Wert in einer einfachen Ganzzahl speichern möchten, können Sie cast long in int eingeben. Sie können Werte von einem Typ explizit mit einem in einen anderen konvertierencast operator wie folgt -

(type_name) expression

In Objective-C verwenden wir im Allgemeinen CGFloat für die Gleitkommaoperation, die im Fall von 32-Bit vom Basistyp des Floats und im Fall von 64-Bit vom Double abgeleitet wird. Betrachten Sie das folgende Beispiel, in dem der Cast-Operator bewirkt, dass die Division einer Ganzzahlvariablen durch eine andere als Gleitkommaoperation ausgeführt wird.

#import <Foundation/Foundation.h>

int main() {
   int sum = 17, count = 5;
   CGFloat mean;

   mean = (CGFloat) sum / count;
   NSLog(@"Value of mean : %f\n", mean );

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-11 01:35:40.047 demo[20634] Value of mean : 3.400000

Hierbei ist zu beachten, dass der Cast-Operator Vorrang vor der Division hat, also der Wert von sum wird zuerst in Typ konvertiert double und schließlich wird es durch die Zählung geteilt, was einen doppelten Wert ergibt.

Typkonvertierungen können implizit sein, was vom Compiler automatisch durchgeführt wird, oder sie können explizit durch die Verwendung von angegeben werden cast operator. Es wird als gute Programmierpraxis angesehen, den Cast-Operator immer dann zu verwenden, wenn Typkonvertierungen erforderlich sind.

Ganzzahlige Förderung

Integer-Promotion ist der Prozess, bei dem Werte vom Integer-Typ "kleiner" als sind int oder unsigned int werden entweder in konvertiert int oder unsigned int. Betrachten Sie ein Beispiel für das Hinzufügen eines Zeichens in einem int -

#import <Foundation/Foundation.h>

int main() {
   int  i = 17;
   char c = 'c';  /* ascii value is 99 */
   int sum;

   sum = i + c;
   NSLog(@"Value of sum : %d\n", sum );

   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-11 01:38:28.492 demo[980] Value of sum : 116

Hier kommt der Wert der Summe als 116, da der Compiler eine Ganzzahl-Heraufstufung durchführt und den Wert von 'c' in ASCII konvertiert, bevor die eigentliche Additionsoperation ausgeführt wird.

Übliche arithmetische Umrechnung

Das usual arithmetic conversionswerden implizit ausgeführt, um ihre Werte in einen gemeinsamen Typ umzuwandeln. Der Compiler führt zuerst eine Ganzzahl-Heraufstufung durch . Wenn Operanden immer noch unterschiedliche Typen haben, werden sie in den Typ konvertiert, der in der folgenden Hierarchie am höchsten erscheint:

Die üblichen arithmetischen Konvertierungen werden weder für die Zuweisungsoperatoren noch für die logischen Operatoren && und || durchgeführt. Nehmen wir das folgende Beispiel, um das Konzept zu verstehen:

#import <Foundation/Foundation.h>

int main() {
   int  i = 17;
   char c = 'c';  /* ascii value is 99 */
   CGFloat sum;

   sum = i + c;
   NSLog(@"Value of sum : %f\n", sum );
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-11 01:41:39.192 demo[15351] Value of sum : 116.000000

Hier ist es einfach zu verstehen, dass das erste c in eine Ganzzahl konvertiert wird, aber da der Endwert float ist, gilt die übliche arithmetische Konvertierung, und der Compiler konvertiert i und c in float und fügt sie hinzu, was ein float-Ergebnis ergibt.

NSLog-Methode

Zum Drucken von Protokollen verwenden wir die NSLog-Methode in der Programmiersprache Objective-C, die wir direkt aus dem Hello World-Beispiel verwendet haben.

Schauen wir uns einen einfachen Code an, der die Wörter "Hello World" druckt -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Hello, World! \n");
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-16 00:32:50.888 demo[16669] Hello, World!

Deaktivieren von Protokollen in Live-Apps

Da die NSLogs, die wir in unserer Anwendung verwenden, in Protokollen des Geräts gedruckt werden und es nicht gut ist, Protokolle in einem Live-Build zu drucken. Daher verwenden wir eine Typdefinition zum Drucken von Protokollen und können diese wie unten gezeigt verwenden.

#import <Foundation/Foundation.h>

#if DEBUG == 0
#define DebugLog(...)
#elif DEBUG == 1
#define DebugLog(...) NSLog(__VA_ARGS__)
#endif

int main() {
   DebugLog(@"Debug log, our custom addition gets \
   printed during debug only" );
   NSLog(@"NSLog gets printed always" );     
   return 0;
}

Wenn wir nun das Programm im Debug-Modus kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-11 02:47:07.723 demo[618] Debug log, our custom addition gets printed during debug only
2013-09-11 02:47:07.723 demo[618] NSLog gets printed always

Wenn wir nun das Programm im Release-Modus kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-11 02:47:45.248 demo[3158] NSLog gets printed always

In der Objective-C-Programmierung wird die Fehlerbehandlung mit der in verfügbaren NSError-Klasse bereitgestellt Foundation framework.

Ein NSError-Objekt kapselt umfangreichere und erweiterbarere Fehlerinformationen, als dies nur mit einem Fehlercode oder einer Fehlerzeichenfolge möglich ist. Die Kernattribute eines NSError-Objekts sind eine Fehlerdomäne (dargestellt durch eine Zeichenfolge), ein domänenspezifischer Fehlercode und ein Benutzerinformationswörterbuch mit anwendungsspezifischen Informationen.

NSError

Objective-C-Programme verwenden NSError-Objekte, um Informationen zu Laufzeitfehlern zu übermitteln, über die Benutzer informiert werden müssen. In den meisten Fällen zeigt ein Programm diese Fehlerinformationen in einem Dialogfeld oder Blatt an. Es kann aber auch die Informationen interpretieren und den Benutzer entweder auffordern, zu versuchen, den Fehler zu beheben, oder versuchen, den Fehler selbst zu korrigieren

NSError-Objekt besteht aus -

  • Domain - Die Fehlerdomäne kann eine der vordefinierten NSError-Domänen sein oder eine beliebige Zeichenfolge, die eine benutzerdefinierte Domäne beschreibt, und die Domäne darf nicht Null sein.

  • Code - Der Fehlercode für den Fehler.

  • User Info - Das userInfo-Wörterbuch für den Fehler und userInfo kann null sein.

Das folgende Beispiel zeigt, wie Sie einen benutzerdefinierten Fehler erstellen

NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
NSString *desc = NSLocalizedString(@"Unable to complete the process", @"");
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo];

Hier ist der vollständige Code des obigen Fehlerbeispiels, der als Referenz auf einen Zeiger übergeben wurde -

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr;
@end

@implementation SampleClass

-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr {
   if(id == 1) {
      return @"Employee Test Name";
   } else {
      NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
      NSString *desc =@"Unable to complete the process";
      NSDictionary *userInfo = [[NSDictionary alloc] 
      initWithObjectsAndKeys:desc,
      @"NSLocalizedDescriptionKey",NULL];  
      *errorPtr = [NSError errorWithDomain:domain code:-101 
      userInfo:userInfo];
      return @"";
   }
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   NSError *error = nil;
   NSString *name1 = [sampleClass getEmployeeNameForID:1 withError:&error];
  
   if(error) {
      NSLog(@"Error finding Name1: %@",error);
   } else {
      NSLog(@"Name1: %@",name1);
   }
   
   error = nil;
   NSString *name2 = [sampleClass getEmployeeNameForID:2 withError:&error];

   if(error) {
      NSLog(@"Error finding Name2: %@",error);
   } else {
      NSLog(@"Name2: %@",name2);
   }

   [pool drain];
   return 0; 
}

Im obigen Beispiel geben wir einen Namen zurück, wenn die ID 1 ist, andernfalls setzen wir das benutzerdefinierte Fehlerobjekt.

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 18:01:00.809 demo[27632] Name1: Employee Test Name
2013-09-14 18:01:00.809 demo[27632] Error finding Name2: Unable to complete the process

Es ist möglich, einige Werte von der Befehlszeile an Ihre Objective-C-Programme zu übergeben, wenn diese ausgeführt werden. Diese Werte werden aufgerufencommand line arguments und oft sind sie für Ihr Programm wichtig, insbesondere wenn Sie Ihr Programm von außen steuern möchten, anstatt diese Werte innerhalb des Codes hart zu codieren.

Die Befehlszeilenargumente werden mit main () - Funktionsargumenten behandelt, wobei argc bezieht sich auf die Anzahl der übergebenen Argumente und argv[]ist ein Zeigerarray, das auf jedes an das Programm übergebene Argument verweist. Im Folgenden finden Sie ein einfaches Beispiel, in dem überprüft wird, ob über die Befehlszeile ein Argument angegeben wurde, und entsprechende Maßnahmen ergriffen werden.

#import <Foundation/Foundation.h>

int main( int argc, char *argv[] ) {
   if( argc == 2 ) {
      NSLog(@"The argument supplied is %s\n", argv[1]);
   } else if( argc > 2 ) {
      NSLog(@"Too many arguments supplied.\n");
   } else {
      NSLog(@"One argument expected.\n");
   }
}

Wenn der obige Code mit einem einzigen Argument kompiliert und ausgeführt wird, z. B. "Testen", wird das folgende Ergebnis erzielt.

2013-09-13 03:01:17.333 demo[7640] The argument supplied is testing

Wenn der obige Code mit zwei Argumenten kompiliert und ausgeführt wird, z. B. Test1 und Test2, wird das folgende Ergebnis erzielt.

2013-09-13 03:01:18.333 demo[7640] Too many arguments supplied.

Wenn der obige Code kompiliert und ausgeführt wird, ohne ein Argument zu übergeben, wird das folgende Ergebnis erzeugt.

2013-09-13 03:01:18.333 demo[7640] One argument expected

Es sollte angemerkt werden, dass argv[0] enthält den Namen des Programms selbst und argv[1]ist ein Zeiger auf das erste angegebene Befehlszeilenargument, und * argv [n] ist das letzte Argument. Wenn keine Argumente angegeben werden, ist argc eins, andernfalls, wenn Sie ein Argument übergeben, dannargc ist auf 2 eingestellt.

Sie übergeben alle durch ein Leerzeichen getrennten Befehlszeilenargumente. Wenn das Argument selbst jedoch ein Leerzeichen enthält, können Sie solche Argumente übergeben, indem Sie sie in doppelte Anführungszeichen oder einfache Anführungszeichen setzen. Lassen Sie uns das obige Beispiel noch einmal neu schreiben, wo wir den Programmnamen drucken und ein Befehlszeilenargument übergeben, indem wir doppelte Anführungszeichen setzen -

#import <Foundation/Foundation.h>

int main( int argc, char *argv[] ) {
   NSLog(@"Program name %s\n", argv[0]);
 
   if( argc == 2 ) {
      NSLog(@"The argument supplied is %s\n", argv[1]);
   } else if( argc > 2 ) {
      NSLog(@"Too many arguments supplied.\n");
   } else {
      NSLog(@"One argument expected.\n");
   }
   
   return 0;
}

Wenn der obige Code mit einem einzelnen Argument kompiliert und ausgeführt wird, das durch Leerzeichen getrennt ist, aber in doppelten Anführungszeichen "Testing1 Testing2" steht, wird das folgende Ergebnis erzielt.

2017-11-30 06:36:59.081 main[71010] Program name main
2017-11-30 06:36:59.082 main[71010] One argument expected.

Der Hauptzweck der Programmiersprache Objective-C besteht darin, der Programmiersprache C Objektorientierung hinzuzufügen. Klassen sind das zentrale Merkmal von Objective-C, das die objektorientierte Programmierung unterstützt und häufig als benutzerdefinierte Typen bezeichnet wird.

Eine Klasse wird verwendet, um die Form eines Objekts anzugeben. Sie kombiniert Datendarstellung und Methoden zum Bearbeiten dieser Daten in einem übersichtlichen Paket. Die Daten und Methoden innerhalb einer Klasse werden als Mitglieder der Klasse bezeichnet.

Ziel-C-Eigenschaften

  • Die Klasse ist nämlich in zwei verschiedenen Abschnitten definiert @interface und @implementation.

  • Fast alles ist in Form von Objekten.

  • Objekte empfangen Nachrichten und Objekte werden häufig als Empfänger bezeichnet.

  • Objekte enthalten Instanzvariablen.

  • Objekte und Instanzvariablen haben Gültigkeitsbereich.

  • Klassen verbergen die Implementierung eines Objekts.

  • Eigenschaften werden verwendet, um den Zugriff auf Klasseninstanzvariablen in anderen Klassen zu ermöglichen.

Ziel-C-Klassendefinitionen

Wenn Sie eine Klasse definieren, definieren Sie einen Entwurf für einen Datentyp. Dies definiert eigentlich keine Daten, aber es definiert, was der Klassenname bedeutet, dh woraus ein Objekt der Klasse besteht und welche Operationen an einem solchen Objekt ausgeführt werden können.

Eine Klassendefinition beginnt mit dem Schlüsselwort @interfacegefolgt vom Namen der Schnittstelle (Klasse); und der Klassenkörper, der von zwei geschweiften Klammern umgeben ist. In Objective-C werden alle Klassen von der aufgerufenen Basisklasse abgeleitetNSObject. Es ist die Oberklasse aller Objective-C-Klassen. Es bietet grundlegende Methoden wie Speicherzuweisung und Initialisierung. Zum Beispiel haben wir den Box-Datentyp mit dem Schlüsselwort definiertclass wie folgt -

@interface Box:NSObject {
   //Instance variables
   double length;    // Length of a box
   double breadth;   // Breadth of a box
}
@property(nonatomic, readwrite) double height;  // Property

@end

Die Instanzvariablen sind privat und nur innerhalb der Klassenimplementierung zugänglich.

Zuweisen und Initialisieren von Objective-C-Objekten

Eine Klasse stellt die Blaupausen für Objekte bereit, sodass im Grunde genommen ein Objekt aus einer Klasse erstellt wird. Wir deklarieren Objekte einer Klasse mit genau der gleichen Art von Deklaration, die wir Variablen von Basistypen deklarieren. Die folgenden Anweisungen deklarieren zwei Objekte der Klasse Box -

Box box1 = [[Box alloc]init];     // Create box1 object of type Box
Box box2 = [[Box alloc]init];     // Create box2 object of type Box

Beide Objekte box1 und box2 haben eine eigene Kopie der Datenelemente.

Zugriff auf die Datenelemente

Auf die Eigenschaften von Objekten einer Klasse kann mit dem direkten Elementzugriffsoperator (.) Zugerechnet werden. Versuchen wir das folgende Beispiel, um die Dinge klar zu machen:

#import <Foundation/Foundation.h>

@interface Box:NSObject {
   double length;    // Length of a box
   double breadth;   // Breadth of a box
   double height;    // Height of a box
}

@property(nonatomic, readwrite) double height;  // Property
-(double) volume;
@end

@implementation Box

@synthesize height; 

-(id)init {
   self = [super init];
   length = 1.0;
   breadth = 1.0;
   return self;
}

-(double) volume {
   return length*breadth*height;
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
   Box *box1 = [[Box alloc]init];    // Create box1 object of type Box
   Box *box2 = [[Box alloc]init];    // Create box2 object of type Box

   double volume = 0.0;             // Store the volume of a box here
 
   // box 1 specification
   box1.height = 5.0; 

   // box 2 specification
   box2.height = 10.0;
  
   // volume of box 1
   volume = [box1 volume];
   NSLog(@"Volume of Box1 : %f", volume);
   
   // volume of box 2
   volume = [box2 volume];
   NSLog(@"Volume of Box2 : %f", volume);
   
   [pool drain];
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-22 21:25:33.314 ClassAndObjects[387:303] Volume of Box1 : 5.000000
2013-09-22 21:25:33.316 ClassAndObjects[387:303] Volume of Box2 : 10.000000

Eigenschaften

In Objective-C werden Eigenschaften eingeführt, um sicherzustellen, dass auf die Instanzvariable der Klasse außerhalb der Klasse zugegriffen werden kann.

  • Eigenschaften beginnen mit @property, das ist ein Schlüsselwort

  • Es folgen Zugriffsspezifizierer, die nichtatomar oder atomar, schreibgeschützt oder schreibgeschützt und stark, unsicher, nicht zurückgehalten oder schwach sind. Dies hängt vom Typ der Variablen ab. Für jeden Zeigertyp können wir strong, unsafe_unretained oder schwach verwenden. In ähnlicher Weise können wir für andere Typen readwrite oder readonly verwenden.

  • Darauf folgt der Datentyp der Variablen.

  • Schließlich haben wir den Eigenschaftsnamen durch ein Semikolon abgeschlossen.

  • Wir können der Implementierungsklasse eine synthetize-Anweisung hinzufügen. Im neuesten XCode wird der Syntheseteil jedoch vom XCode übernommen, und Sie müssen keine Synthesize-Anweisung einschließen.

Es ist nur mit den Eigenschaften möglich, auf die Instanzvariablen der Klasse zuzugreifen. Tatsächlich werden für die Eigenschaften intern Getter- und Setter-Methoden erstellt.

Nehmen wir zum Beispiel an, wir haben eine Eigenschaft @property (nonatomic ,readonly ) BOOL isDone. Unter der Haube befinden sich Setter und Getter, die wie unten gezeigt erstellt wurden.

-(void)setIsDone(BOOL)isDone;
-(BOOL)isDone;

Eines der wichtigsten Konzepte in der objektorientierten Programmierung ist das der Vererbung. Durch Vererbung können wir eine Klasse in Bezug auf eine andere Klasse definieren, was das Erstellen und Verwalten einer Anwendung erleichtert. Dies bietet auch die Möglichkeit, die Codefunktionalität und die schnelle Implementierungszeit wiederzuverwenden.

Beim Erstellen einer Klasse kann der Programmierer festlegen, dass die neue Klasse die Mitglieder einer vorhandenen Klasse erben soll, anstatt vollständig neue Datenelemente und Elementfunktionen zu schreiben. Diese vorhandene Klasse heißtbase Klasse, und die neue Klasse wird als die bezeichnet derived Klasse.

Die Idee der Vererbung setzt die is aBeziehung. Zum Beispiel Säugetier-IS-A-Tier, Hund-IS-A-Säugetier, daher auch Hund-IS-A-Tier und so weiter.

Basis- und abgeleitete Klassen

Objective-C erlaubt nur eine mehrstufige Vererbung, dh es kann nur eine Basisklasse haben, erlaubt jedoch eine mehrstufige Vererbung. Alle Klassen in Objective-C werden von der Oberklasse abgeleitetNSObject.

@interface derived-class: base-class

Betrachten Sie eine Basisklasse Person und seine abgeleitete Klasse Employee wie folgt -

#import <Foundation/Foundation.h>
 
@interface Person : NSObject {
   NSString *personName;
   NSInteger personAge;
}

- (id)initWithName:(NSString *)name andAge:(NSInteger)age;
- (void)print;

@end

@implementation Person

- (id)initWithName:(NSString *)name andAge:(NSInteger)age {
   personName = name;
   personAge = age;
   return self;
}

- (void)print {
   NSLog(@"Name: %@", personName);
   NSLog(@"Age: %ld", personAge);
}

@end

@interface Employee : Person {
   NSString *employeeEducation;
}

- (id)initWithName:(NSString *)name andAge:(NSInteger)age 
  andEducation:(NSString *)education;
- (void)print;
@end

@implementation Employee

- (id)initWithName:(NSString *)name andAge:(NSInteger)age 
   andEducation: (NSString *)education {
      personName = name;
      personAge = age;
      employeeEducation = education;
      return self;
   }

- (void)print {
   NSLog(@"Name: %@", personName);
   NSLog(@"Age: %ld", personAge);
   NSLog(@"Education: %@", employeeEducation);
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];        
   NSLog(@"Base class Person Object");
   Person *person = [[Person alloc]initWithName:@"Raj" andAge:5];
   [person print];
   NSLog(@"Inherited Class Employee Object");
   Employee *employee = [[Employee alloc]initWithName:@"Raj" 
   andAge:5 andEducation:@"MBA"];
   [employee print];        
   [pool drain];
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-22 21:20:09.842 Inheritance[349:303] Base class Person Object
2013-09-22 21:20:09.844 Inheritance[349:303] Name: Raj
2013-09-22 21:20:09.844 Inheritance[349:303] Age: 5
2013-09-22 21:20:09.845 Inheritance[349:303] Inherited Class Employee Object
2013-09-22 21:20:09.845 Inheritance[349:303] Name: Raj
2013-09-22 21:20:09.846 Inheritance[349:303] Age: 5
2013-09-22 21:20:09.846 Inheritance[349:303] Education: MBA

Zugangskontrolle und Vererbung

Eine abgeleitete Klasse kann auf alle privaten Mitglieder ihrer Basisklasse zugreifen, wenn sie in der Schnittstellenklasse definiert ist. Sie kann jedoch nicht auf private Mitglieder zugreifen, die in der Implementierungsdatei definiert sind.

Wir können die verschiedenen Zugriffstypen auf folgende Weise zusammenfassen, je nachdem, wer auf sie zugreifen kann:

Eine abgeleitete Klasse erbt alle Basisklassenmethoden und -variablen mit den folgenden Ausnahmen:

  • Auf Variablen, die mit Hilfe von Erweiterungen in der Implementierungsdatei deklariert wurden, kann nicht zugegriffen werden.

  • Auf Methoden, die mit Hilfe von Erweiterungen in der Implementierungsdatei deklariert wurden, kann nicht zugegriffen werden.

  • Wenn die geerbte Klasse die Methode in der Basisklasse implementiert, wird die Methode in der abgeleiteten Klasse ausgeführt.

Das Wort polymorphismbedeutet, viele Formen zu haben. In der Regel tritt Polymorphismus auf, wenn es eine Hierarchie von Klassen gibt, die durch Vererbung miteinander verbunden sind.

Objective-C-Polymorphismus bedeutet, dass ein Aufruf einer Mitgliedsfunktion dazu führt, dass abhängig vom Objekttyp, der die Funktion aufruft, eine andere Funktion ausgeführt wird.

Betrachten Sie das Beispiel, wir haben eine Klasse Form, die die grundlegende Schnittstelle für alle Formen bereitstellt. Quadrat und Rechteck werden von der Basisklasse Form abgeleitet.

Wir haben die Methode printArea, die über die OOP-Funktion angezeigt wird polymorphism.

#import <Foundation/Foundation.h>

@interface Shape : NSObject {
   CGFloat area;
}

- (void)printArea;
- (void)calculateArea;
@end

@implementation Shape
- (void)printArea {
   NSLog(@"The area is %f", area);
}

- (void)calculateArea {

}

@end

@interface Square : Shape {
   CGFloat length;
}

- (id)initWithSide:(CGFloat)side;
- (void)calculateArea;

@end

@implementation Square
- (id)initWithSide:(CGFloat)side {
   length = side;
   return self;
}

- (void)calculateArea {
   area = length * length;
}

- (void)printArea {
   NSLog(@"The area of square is %f", area);
}

@end

@interface Rectangle : Shape {
   CGFloat length;
   CGFloat breadth;
}

- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth;
@end

@implementation Rectangle
- (id)initWithLength:(CGFloat)rLength andBreadth:(CGFloat)rBreadth {
   length = rLength;
   breadth = rBreadth;
   return self;
}

- (void)calculateArea {
   area = length * breadth;
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   Shape *square = [[Square alloc]initWithSide:10.0];
   [square calculateArea];
   [square printArea];
   Shape *rect = [[Rectangle alloc]
   initWithLength:10.0 andBreadth:5.0];
   [rect calculateArea];
   [rect printArea];        
   [pool drain];
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-22 21:21:50.785 Polymorphism[358:303] The area of square is 100.000000
2013-09-22 21:21:50.786 Polymorphism[358:303] The area is 50.000000

Im obigen Beispiel wird basierend auf der Verfügbarkeit der Methoden berechneArea und printArea entweder die Methode in der Basisklasse oder die abgeleitete Klasse ausgeführt.

Polymorphismus behandelt das Umschalten von Methoden zwischen der Basisklasse und der abgeleiteten Klasse basierend auf der Methodenimplementierung der beiden Klassen.

Alle Objective-C-Programme bestehen aus den folgenden zwei grundlegenden Elementen:

  • Program statements (code) - Dies ist der Teil eines Programms, der Aktionen ausführt und als Methoden bezeichnet wird.

  • Program data - Die Daten sind die Informationen des Programms, die von den Programmfunktionen betroffen sind.

Die Kapselung ist ein objektorientiertes Programmierkonzept, das die Daten und Funktionen, die die Daten manipulieren, zusammenhält und sowohl vor Störungen von außen als auch vor Missbrauch schützt. Die Datenkapselung führte zu dem wichtigen OOP-Konzept vondata hiding.

Data encapsulation ist ein Mechanismus zum Bündeln der Daten und der Funktionen, die sie verwenden, und data abstraction ist ein Mechanismus, bei dem nur die Schnittstellen verfügbar gemacht und die Implementierungsdetails vor dem Benutzer verborgen werden.

Objective-C unterstützt die Eigenschaften der Kapselung und des Versteckens von Daten durch die Erstellung benutzerdefinierter Typen, die als aufgerufen werden classes. Zum Beispiel -

@interface Adder : NSObject {
   NSInteger total;
}

- (id)initWithInitialNumber:(NSInteger)initialNumber;
- (void)addNumber:(NSInteger)newNumber;
- (NSInteger)getTotal;

@end

Die variable Summe ist privat und wir können nicht von außerhalb der Klasse zugreifen. Dies bedeutet, dass nur andere Mitglieder der Adder-Klasse und kein anderer Teil Ihres Programms auf sie zugreifen können. Dies ist eine Möglichkeit, wie die Einkapselung erreicht wird.

Methoden innerhalb der Schnittstellendatei sind zugänglich und öffentlich zugänglich.

Es gibt private Methoden, die mit Hilfe von geschrieben werden extensions, die wir in den kommenden Kapiteln lernen werden.

Beispiel für die Datenkapselung

Jedes Objective-C-Programm, in dem Sie eine Klasse mit öffentlichen und privaten Mitgliedsvariablen implementieren, ist ein Beispiel für Datenkapselung und Datenabstraktion. Betrachten Sie das folgende Beispiel -

#import <Foundation/Foundation.h>

@interface Adder : NSObject {
   NSInteger total;
}

- (id)initWithInitialNumber:(NSInteger)initialNumber;
- (void)addNumber:(NSInteger)newNumber;
- (NSInteger)getTotal;

@end

@implementation Adder
-(id)initWithInitialNumber:(NSInteger)initialNumber {
   total = initialNumber;
   return self;
}

- (void)addNumber:(NSInteger)newNumber {
   total = total + newNumber;
}

- (NSInteger)getTotal {
   return total;
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];        
   Adder *adder = [[Adder alloc]initWithInitialNumber:10];
   [adder addNumber:5];
   [adder addNumber:4];
   
   NSLog(@"The total is %ld",[adder getTotal]);
   [pool drain];
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-22 21:17:30.485 DataEncapsulation[317:303] The total is 19

Die obige Klasse addiert Zahlen und gibt die Summe zurück. Die öffentlichen MitgliederaddNum und getTotal sind die Schnittstellen zur Außenwelt und ein Benutzer muss sie kennen, um die Klasse verwenden zu können. Das private Mitgliedtotal ist etwas, das vor der Außenwelt verborgen ist, aber benötigt wird, damit die Klasse richtig funktioniert.

Strategie entwerfen

Die meisten von uns haben durch bittere Erfahrung gelernt, Klassenmitglieder standardmäßig privat zu machen, es sei denn, wir müssen sie wirklich entlarven. Das ist einfach gutencapsulation.

Es ist wichtig, die Datenkapselung zu verstehen, da sie eine der Hauptfunktionen aller OOP-Sprachen (Object-Oriented Programming) einschließlich Objective-C ist.

Manchmal stellen Sie möglicherweise fest, dass Sie eine vorhandene Klasse erweitern möchten, indem Sie ein Verhalten hinzufügen, das nur in bestimmten Situationen nützlich ist. Um eine solche Erweiterung zu vorhandenen Klassen hinzuzufügen, bietet Objective-Ccategories und extensions.

Wenn Sie einer vorhandenen Klasse möglicherweise eine Methode hinzufügen müssen, um Funktionen hinzuzufügen, die es einfacher machen, etwas in Ihrer eigenen Anwendung zu tun, ist es am einfachsten, eine Kategorie zu verwenden.

Die Syntax zum Deklarieren einer Kategorie verwendet das Schlüsselwort @interface, genau wie eine Standardbeschreibung der Objective-C-Klasse, zeigt jedoch keine Vererbung von einer Unterklasse an. Stattdessen wird der Name der Kategorie wie folgt in Klammern angegeben:

@interface ClassName (CategoryName)

@end

Merkmale der Kategorie

  • Eine Kategorie kann für jede Klasse deklariert werden, auch wenn Sie nicht über den ursprünglichen Quellcode der Implementierung verfügen.

  • Alle Methoden, die Sie in einer Kategorie deklarieren, stehen allen Instanzen der ursprünglichen Klasse sowie allen Unterklassen der ursprünglichen Klasse zur Verfügung.

  • Zur Laufzeit gibt es keinen Unterschied zwischen einer Methode, die von einer Kategorie hinzugefügt wurde, und einer Methode, die von der ursprünglichen Klasse implementiert wurde.

Schauen wir uns nun eine Beispielkategorie-Implementierung an. Fügen wir der Kakao-Klasse NSString eine Kategorie hinzu. Diese Kategorie ermöglicht es uns, eine neue Methode getCopyRightString hinzuzufügen, die uns bei der Rückgabe der Copyright-Zeichenfolge hilft. Es ist unten gezeigt.

#import <Foundation/Foundation.h>

@interface NSString(MyAdditions)
+(NSString *)getCopyRightString;
@end

@implementation NSString(MyAdditions)

+(NSString *)getCopyRightString {
   return @"Copyright TutorialsPoint.com 2013";
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSString *copyrightString = [NSString getCopyRightString];
   NSLog(@"Accessing Category: %@",copyrightString);
   
   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-22 21:19:12.125 Categories[340:303] Accessing Category: Copyright TutorialsPoint.com 2013

Obwohl alle von einer Kategorie hinzugefügten Methoden für alle Instanzen der Klasse und ihrer Unterklassen verfügbar sind, müssen Sie die Kategorie-Header-Datei in jede Quellcodedatei importieren, in der Sie die zusätzlichen Methoden verwenden möchten. Andernfalls werden Sie darauf stoßen Compiler-Warnungen und -Fehler.

In unserem Beispiel haben wir, da wir nur eine einzelne Klasse haben, keine Header-Dateien eingefügt. In einem solchen Fall sollten wir die Header-Dateien wie oben beschrieben einschließen.

Bevor ich mit dem Posieren in Objective-C beginne, möchte ich Sie darauf hinweisen, dass das Posieren in Mac OS X 10.5 für veraltet erklärt wurde und danach nicht mehr verwendet werden kann. Wer sich also nicht um diese veralteten Methoden kümmert, kann dieses Kapitel überspringen.

Mit Objective-C kann eine Klasse eine andere Klasse innerhalb eines Programms vollständig ersetzen. Die ersetzende Klasse soll sich als Zielklasse "ausgeben".

Bei den Versionen, die das Posieren unterstützen, werden stattdessen alle an die Zielklasse gesendeten Nachrichten von der Posierungsklasse empfangen.

NSObject enthält die MethodeposeAsClass:, mit der wir die vorhandene Klasse wie oben beschrieben ersetzen können.

Einschränkungen beim Posieren

  • Eine Klasse darf sich nur als eine ihrer direkten oder indirekten Oberklassen ausgeben.

  • Die posierende Klasse darf keine neuen Instanzvariablen definieren, die in der Zielklasse fehlen (obwohl sie Methoden definieren oder überschreiben kann).

  • Die Zielklasse hat möglicherweise vor dem Aufstellen keine Nachrichten erhalten.

  • Eine posierende Klasse kann überschriebene Methoden über super aufrufen und so die Implementierung der Zielklasse einbeziehen.

  • Eine posierende Klasse kann in Kategorien definierte Methoden überschreiben.

#import <Foundation/Foundation.h>

@interface MyString : NSString

@end

@implementation MyString

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target
withString:(NSString *)replacement {
   NSLog(@"The Target string is %@",target);
   NSLog(@"The Replacement string is %@",replacement);
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   [MyString poseAsClass:[NSString class]];
   NSString *string = @"Test";
   [string stringByReplacingOccurrencesOfString:@"a" withString:@"c"];
   
   [pool drain];
   return 0;
}

Wenn wir nun das Programm unter einem älteren Mac OS X (V_10.5 oder früher) kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-22 21:23:46.829 Posing[372:303] The Target string is a
2013-09-22 21:23:46.830 Posing[372:303] The Replacement string is c

Im obigen Beispiel haben wir gerade die ursprüngliche Methode mit unserer Implementierung verschmutzt, und dies wird bei allen NSString-Vorgängen mit der obigen Methode beeinträchtigt.

Eine Klassenerweiterung weist eine gewisse Ähnlichkeit mit einer Kategorie auf, kann jedoch nur einer Klasse hinzugefügt werden, für die Sie zur Kompilierungszeit über den Quellcode verfügen (die Klasse wird gleichzeitig mit der Klassenerweiterung kompiliert).

Die von einer Klassenerweiterung deklarierten Methoden werden im Implementierungsblock für die ursprüngliche Klasse implementiert, sodass Sie beispielsweise keine Klassenerweiterung für eine Framework-Klasse wie eine Cocoa- oder Cocoa Touch-Klasse wie NSString deklarieren können.

Erweiterungen sind eigentlich Kategorien ohne den Kategorienamen. Es wird oft als bezeichnetanonymous categories.

Die Syntax zum Deklarieren einer Erweiterung verwendet das Schlüsselwort @interface, genau wie eine Standardbeschreibung der Objective-C-Klasse, zeigt jedoch keine Vererbung von einer Unterklasse an. Stattdessen werden nur Klammern hinzugefügt, wie unten gezeigt -

@interface ClassName ()

@end

Eigenschaften von Erweiterungen

  • Eine Erweiterung kann nicht für eine Klasse deklariert werden, sondern nur für die Klassen, für die wir ursprünglich den Quellcode implementiert haben.

  • Eine Erweiterung fügt private Methoden und private Variablen hinzu, die nur für die Klasse spezifisch sind.

  • Jede in den Erweiterungen deklarierte Methode oder Variable ist selbst für die geerbten Klassen nicht zugänglich.

Erweiterungsbeispiel

Erstellen wir eine Klasse SampleClass mit einer Erweiterung. Lassen Sie uns in der Erweiterung eine private Variable internalID haben.

Lassen Sie uns dann eine Methode getExternalID verwenden, die die externalID nach der Verarbeitung der internalID zurückgibt.

Das Beispiel wird unten gezeigt und dies funktioniert nicht mit dem Online-Compiler.

#import <Foundation/Foundation.h>

@interface SampleClass : NSObject {
   NSString *name;
}

- (void)setInternalID;
- (NSString *)getExternalID;

@end

@interface SampleClass() {
   NSString *internalID;
}

@end

@implementation SampleClass

- (void)setInternalID {
   internalID = [NSString stringWithFormat: 
   @"UNIQUEINTERNALKEY%dUNIQUEINTERNALKEY",arc4random()%100];
}

- (NSString *)getExternalID {
   return [internalID stringByReplacingOccurrencesOfString: 
   @"UNIQUEINTERNALKEY" withString:@""];
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass setInternalID];
   NSLog(@"ExternalID: %@",[sampleClass getExternalID]);        
   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-22 21:18:31.754 Extensions[331:303] ExternalID: 51

Im obigen Beispiel sehen wir, dass die interne ID nicht direkt zurückgegeben wird. Wir entfernen hier den UNIQUEINTERNALKEY und stellen nur den verbleibenden Wert der Methode getExternalID zur Verfügung.

Das obige Beispiel verwendet nur eine Zeichenfolgenoperation, kann jedoch viele Funktionen wie Verschlüsselung / Entschlüsselung usw. enthalten.

Mit Objective-C können Sie Protokolle definieren, die die Methoden deklarieren, die voraussichtlich für eine bestimmte Situation verwendet werden. Protokolle werden in den Klassen implementiert, die dem Protokoll entsprechen.

Ein einfaches Beispiel wäre eine Klasse zur Verarbeitung von Netzwerk-URLs. Sie verfügt über ein Protokoll mit Methoden wie der Methode processCompleted delegate, die die aufrufende Klasse anzeigt, sobald der Vorgang zum Abrufen der Netzwerk-URL abgeschlossen ist.

Eine Syntax des Protokolls ist unten gezeigt.

@protocol ProtocolName
@required
// list of required methods
@optional
// list of optional methods
@end

Die Methoden unter Schlüsselwort @required muss in den Klassen implementiert werden, die dem Protokoll und den Methoden unter entsprechen @optional Schlüsselwörter sind optional zu implementieren.

Hier ist die Syntax für eine Klasse, die dem Protokoll entspricht

@interface MyClass : NSObject <MyProtocol>
...
@end

Dies bedeutet, dass jede Instanz von MyClass nicht nur auf die in der Schnittstelle speziell deklarierten Methoden reagiert, sondern dass MyClass auch Implementierungen für die erforderlichen Methoden in MyProtocol bereitstellt. Es ist nicht erforderlich, die Protokollmethoden in der Klassenschnittstelle neu zu deklarieren - die Übernahme des Protokolls ist ausreichend.

Wenn Sie eine Klasse benötigen, um mehrere Protokolle zu übernehmen, können Sie diese als durch Kommas getrennte Liste angeben. Wir haben ein Delegatenobjekt, das die Referenz des aufrufenden Objekts enthält, das das Protokoll implementiert.

Ein Beispiel ist unten gezeigt.

#import <Foundation/Foundation.h>

@protocol PrintProtocolDelegate
- (void)processCompleted;

@end

@interface PrintClass :NSObject {
   id delegate;
}

- (void) printDetails;
- (void) setDelegate:(id)newDelegate;
@end

@implementation PrintClass
- (void)printDetails {
   NSLog(@"Printing Details");
   [delegate processCompleted];
}

- (void) setDelegate:(id)newDelegate {
   delegate = newDelegate;
}

@end

@interface SampleClass:NSObject<PrintProtocolDelegate>
- (void)startAction;

@end

@implementation SampleClass
- (void)startAction {
   PrintClass *printClass = [[PrintClass alloc]init];
   [printClass setDelegate:self];
   [printClass printDetails];
}

-(void)processCompleted {
   NSLog(@"Printing Process Completed");
}

@end

int main(int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass startAction];
   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-22 21:15:50.362 Protocols[275:303] Printing Details
2013-09-22 21:15:50.364 Protocols[275:303] Printing Process Completed

Im obigen Beispiel haben wir gesehen, wie die delgate-Methoden aufgerufen und ausgeführt werden. Es beginnt mit startAction. Sobald der Prozess abgeschlossen ist, wird die Delegatmethode processCompleted aufgerufen, um den Abschluss der Operation anzuzeigen.

In jeder iOS- oder Mac-App wird niemals ein Programm ohne Delegierten implementiert. Daher ist es wichtig, dass wir die Verwendung von Delegierten verstehen. Delegatenobjekte sollten den Eigenschaftstyp unsafe_unretained verwenden, um Speicherverluste zu vermeiden.

Die dynamische Bindung bestimmt die Methode, die zur Laufzeit anstatt zur Kompilierungszeit aufgerufen werden soll. Die dynamische Bindung wird auch als späte Bindung bezeichnet.

In Objective-C werden alle Methoden zur Laufzeit dynamisch aufgelöst. Der genaue ausgeführte Code wird sowohl vom Methodennamen (dem Selektor) als auch vom empfangenden Objekt bestimmt.

Dynamische Bindung ermöglicht Polymorphismus. Betrachten Sie beispielsweise eine Sammlung von Objekten, einschließlich Rechteck und Quadrat. Jedes Objekt verfügt über eine eigene Implementierung einer printArea-Methode.

Im folgenden Codefragment wird zur Laufzeit der tatsächliche Code bestimmt, der vom Ausdruck [anObject printArea] ausgeführt werden soll. Das Laufzeitsystem verwendet den Selektor für den Methodenlauf, um die entsprechende Methode in der Klasse von anObject zu identifizieren, die sich als solche herausstellt.

Schauen wir uns einen einfachen Code an, der die dynamische Bindung erklärt.

#import <Foundation/Foundation.h>

@interface Square:NSObject {
   float area;
}

- (void)calculateAreaOfSide:(CGFloat)side;
- (void)printArea;
@end

@implementation Square
- (void)calculateAreaOfSide:(CGFloat)side {
   area = side * side;
}

- (void)printArea {
   NSLog(@"The area of square is %f",area);
}

@end

@interface Rectangle:NSObject {
   float area;
}

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth;
- (void)printArea;
@end

@implementation  Rectangle

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth {
   area = length * breadth;
}

- (void)printArea {
   NSLog(@"The area of Rectangle is %f",area);
}

@end

int main() {
   Square *square = [[Square alloc]init];
   [square calculateAreaOfSide:10.0];
   
   Rectangle *rectangle = [[Rectangle alloc]init];
   [rectangle calculateAreaOfLength:10.0 andBreadth:5.0];
   
   NSArray *shapes = [[NSArray alloc]initWithObjects: square, rectangle,nil];
   id object1 = [shapes objectAtIndex:0];
   [object1 printArea];
   
   id object2 = [shapes objectAtIndex:1];
   [object2 printArea];
   
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-28 07:42:29.821 demo[4916] The area of square is 100.000000
2013-09-28 07:42:29.821 demo[4916] The area of Rectangle is 50.000000

Wie Sie im obigen Beispiel sehen können, wird die printArea-Methode zur Laufzeit dynamisch ausgewählt. Es ist ein Beispiel für die dynamische Bindung und in vielen Situationen sehr nützlich, wenn es um ähnliche Objekte geht.

Wir können eine Unterklasse innerhalb eines Klassenclusters erstellen, die eine Klasse definiert, in die ein Objekt eingebettet ist. Diese Klassenobjekte sind zusammengesetzte Objekte.

Sie fragen sich vielleicht, was ein Klassencluster ist. Wir werden also zuerst sehen, was ein Klassencluster ist.

Klassencluster

Klassencluster sind ein Entwurfsmuster, das das Foundation-Framework in großem Umfang verwendet. Klassencluster gruppieren eine Reihe privater konkreter Unterklassen unter einer öffentlichen abstrakten Oberklasse. Die Gruppierung von Klassen auf diese Weise vereinfacht die öffentlich sichtbare Architektur eines objektorientierten Frameworks, ohne dessen Funktionsreichtum zu verringern. Klassencluster basieren auf dem Entwurfsmuster von Abstract Factory.

Um es einfach zu machen, erstellen wir nicht mehrere Klassen für ähnliche Funktionen, sondern eine einzelne Klasse, deren Handhabung auf der Grundlage des Eingabewerts erfolgt.

In NSNumber gibt es beispielsweise viele Klassencluster wie char, int, bool usw. Wir gruppieren sie alle zu einer einzigen Klasse, die sich um die Abwicklung ähnlicher Vorgänge in einer einzigen Klasse kümmert. NSNumber verpackt den Wert dieser primitiven Typen tatsächlich in Objekte.

Was genau ist ein zusammengesetztes Objekt?

Durch Einbetten eines privaten Clusterobjekts in ein Objekt unseres eigenen Designs erstellen wir ein zusammengesetztes Objekt. Dieses zusammengesetzte Objekt kann sich für seine grundlegende Funktionalität auf das Clusterobjekt verlassen und nur Nachrichten abfangen, die das zusammengesetzte Objekt auf eine bestimmte Weise verarbeiten möchte. Diese Architektur reduziert die Menge an Code, die wir schreiben müssen, und ermöglicht es Ihnen, den getesteten Code des Foundation Framework zu nutzen.

Dies wird in der folgenden Abbildung erläutert.

Das zusammengesetzte Objekt muss sich selbst als Unterklasse der abstrakten Oberklasse des Clusters deklarieren. Als Unterklasse muss sie die primitiven Methoden der Oberklasse überschreiben. Es kann auch abgeleitete Methoden überschreiben, dies ist jedoch nicht erforderlich, da die abgeleiteten Methoden die primitiven Methoden verarbeiten.

Die Zählmethode der NSArray-Klasse ist ein Beispiel. Die Implementierung einer Methode, die das intervenierende Objekt überschreibt, kann so einfach sein wie:

- (unsigned)count  {
   return [embeddedObject count];
}

Im obigen Beispiel ist das eingebettete Objekt tatsächlich vom Typ NSArray.

Ein Beispiel für ein zusammengesetztes Objekt

Um ein vollständiges Beispiel zu sehen, schauen wir uns das Beispiel aus der Apple-Dokumentation an, die unten angegeben ist.

#import <Foundation/Foundation.h>

@interface ValidatingArray : NSMutableArray {
   NSMutableArray *embeddedArray;
}

+ validatingArray;
- init;
- (unsigned)count;
- objectAtIndex:(unsigned)index;
- (void)addObject:object;
- (void)replaceObjectAtIndex:(unsigned)index withObject:object;
- (void)removeLastObject;
- (void)insertObject:object atIndex:(unsigned)index;
- (void)removeObjectAtIndex:(unsigned)index;

@end

@implementation ValidatingArray
- init {
   self = [super init];
   if (self) {
      embeddedArray = [[NSMutableArray allocWithZone:[self zone]] init];
   }
   return self;
}

+ validatingArray {
   return [[self alloc] init] ;
}

- (unsigned)count {
   return [embeddedArray count];
}

- objectAtIndex:(unsigned)index {
   return [embeddedArray objectAtIndex:index];
}

- (void)addObject:(id)object {
   if (object != nil) {
      [embeddedArray addObject:object];
   }
}

- (void)replaceObjectAtIndex:(unsigned)index withObject:(id)object; {
   if (index <[embeddedArray count] && object != nil) {
      [embeddedArray replaceObjectAtIndex:index withObject:object];
   }
}

- (void)removeLastObject; {
   if ([embeddedArray count] > 0) {
      [embeddedArray removeLastObject];
   }
}

- (void)insertObject:(id)object atIndex:(unsigned)index; {
   if (object != nil) {
      [embeddedArray insertObject:object atIndex:index];
   }
}

- (void)removeObjectAtIndex:(unsigned)index; {
   if (index <[embeddedArray count]) {
      [embeddedArray removeObjectAtIndex:index];
   }
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   ValidatingArray *validatingArray = [ValidatingArray validatingArray];
   
   [validatingArray addObject:@"Object1"];
   [validatingArray addObject:@"Object2"];
   [validatingArray addObject:[NSNull null]];
   [validatingArray removeObjectAtIndex:2];
   NSString *aString = [validatingArray objectAtIndex:1];
   NSLog(@"The value at Index 1 is %@",aString);
   [pool drain];
   
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-28 22:03:54.294 demo[6247] The value at Index 1 is Object2

Im obigen Beispiel können wir sehen, dass das Überprüfen der einen Funktion des Arrays das Hinzufügen von Nullobjekten nicht zulässt, was im normalen Szenario zum Absturz führt. Aber unser Validierungsarray kümmert sich darum. In ähnlicher Weise fügt jede Methode zum Validieren des Arrays Validierungsprozesse hinzu, abgesehen von der normalen Abfolge von Operationen.

Wenn Sie auf die Apple-Dokumentation verweisen, sehen Sie die Details des Foundation-Frameworks wie unten angegeben.

Das Foundation-Framework definiert eine Basisschicht aus Objective-C-Klassen. Zusätzlich zur Bereitstellung einer Reihe nützlicher primitiver Objektklassen werden verschiedene Paradigmen eingeführt, die Funktionen definieren, die nicht von der Objective-C-Sprache abgedeckt werden. Das Foundation Framework wurde unter Berücksichtigung dieser Ziele entwickelt -

  • Stellen Sie einen kleinen Satz grundlegender Dienstprogrammklassen bereit.

  • Erleichtern Sie die Softwareentwicklung, indem Sie einheitliche Konventionen für Dinge wie die Freigabe einführen.

  • Unterstützt Unicode-Zeichenfolgen, Objektpersistenz und Objektverteilung.

  • Bieten Sie ein gewisses Maß an Betriebssystemunabhängigkeit, um die Portabilität zu verbessern.

Das Framework wurde von NeXTStep entwickelt, das von Apple übernommen wurde, und diese Foundation-Klassen wurden Teil von Mac OS X und iOS.

Da es von NeXTStep entwickelt wurde, hat es das Klassenpräfix "NS".

Wir haben Foundation Framework in allen unseren Beispielprogrammen verwendet. Es ist fast ein Muss, Foundation Framework zu verwenden.

Im Allgemeinen verwenden wir so etwas wie #import <Foundation/NSString.h> Um eine Objective-C-Klasse zu importieren, aber um zu vermeiden, dass zu viele Klassen importiert werden, wird alles in importiert #import <Foundation/Foundation.h>.

NSObject ist die Basisklasse aller Objekte, einschließlich der Foundation Kit-Klassen. Es bietet die Methoden für die Speicherverwaltung. Es bietet auch eine grundlegende Schnittstelle zum Laufzeitsystem und die Möglichkeit, sich als Objective-C-Objekte zu verhalten. Es hat keine Basisklasse und ist die Wurzel für alle Klassen.

Foundation-Klassen basieren auf Funktionalität

Sr.Nr. Schleifentyp & Beschreibung
1 Datenspeicher

NSArray, NSDictionary und NSSet bieten Speicherplatz für Objective-C-Objekte jeder Klasse.

2 Text und Zeichenfolgen

NSCharacterSet repräsentiert verschiedene Gruppierungen von Zeichen, die von den Klassen NSString und NSScanner verwendet werden. Die NSString-Klassen stellen Textzeichenfolgen dar und bieten Methoden zum Suchen, Kombinieren und Vergleichen von Zeichenfolgen. Ein NSScanner-Objekt wird verwendet, um Zahlen und Wörter von einem NSString-Objekt zu scannen.

3 Daten und Zeiten

Die Klassen NSDate, NSTimeZone und NSCalendar speichern Zeiten und Daten und repräsentieren Kalenderinformationen. Sie bieten Methoden zur Berechnung von Datums- und Zeitunterschieden. Zusammen mit NSLocale bieten sie Methoden zum Anzeigen von Datums- und Uhrzeitangaben in vielen Formaten sowie zum Anpassen von Uhrzeiten und Datumsangaben basierend auf dem Standort in der Welt.

4 Ausnahmebehandlung

Die Ausnahmebehandlung wird zur Behandlung unerwarteter Situationen verwendet und in Objective-C mit NSException angeboten.

5 Dateiverwaltung

Die Dateiverwaltung erfolgt mit Hilfe der Klasse NSFileManager.

6 URL-Ladesystem

Eine Reihe von Klassen und Protokollen, die den Zugriff auf gängige Internetprotokolle ermöglichen.

Schnelle Aufzählung ist eine Funktion von Objective-C, die beim Aufzählen einer Sammlung hilft. Um über die schnelle Aufzählung Bescheid zu wissen, müssen wir zuerst über die Sammlung Bescheid wissen, was im folgenden Abschnitt erläutert wird.

Sammlungen in Ziel-C

Sammlungen sind grundlegende Konstrukte. Es wird verwendet, um andere Objekte zu halten und zu verwalten. Der gesamte Zweck einer Sammlung besteht darin, dass sie eine gängige Methode zum effizienten Speichern und Abrufen von Objekten bietet.

Es gibt verschiedene Arten von Sammlungen. Während sie alle den gleichen Zweck erfüllen, andere Objekte halten zu können, unterscheiden sie sich hauptsächlich in der Art und Weise, wie Objekte abgerufen werden. Die in Objective-C am häufigsten verwendeten Sammlungen sind -

  • NSSet
  • NSArray
  • NSDictionary
  • NSMutableSet
  • NSMutableArray
  • NSMutableDictionary

Wenn Sie mehr über diese Strukturen erfahren möchten, lesen Sie bitte die Datenspeicherung in Foundation Framework .

Syntax für schnelle Aufzählung

for (classType variable in collectionObject ) { 
  statements 
}

Hier ist ein Beispiel für eine schnelle Aufzählung.

#import <Foundation/Foundation.h>

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSArray *array = [[NSArray alloc]
   initWithObjects:@"string1", @"string2",@"string3",nil];
   
   for(NSString *aString in array) {
      NSLog(@"Value: %@",aString);
   }
   
   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-28 06:26:22.835 demo[7426] Value: string1
2013-09-28 06:26:22.836 demo[7426] Value: string2
2013-09-28 06:26:22.836 demo[7426] Value: string3

Wie Sie in der Ausgabe sehen können, wird jedes der Objekte im Array in einer Reihenfolge gedruckt.

Schnelle Aufzählung rückwärts

for (classType variable in [collectionObject reverseObjectEnumerator] ) { 
  statements 
}

Hier ist ein Beispiel für reverseObjectEnumerator in schneller Aufzählung.

#import <Foundation/Foundation.h>

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSArray *array = [[NSArray alloc]
   initWithObjects:@"string1", @"string2",@"string3",nil];
   
   for(NSString *aString in [array reverseObjectEnumerator]) {
      NSLog(@"Value: %@",aString);
   }
   
   [pool drain];
   return 0;
}

Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.

2013-09-28 06:27:51.025 demo[12742] Value: string3
2013-09-28 06:27:51.025 demo[12742] Value: string2
2013-09-28 06:27:51.025 demo[12742] Value: string1

Wie Sie in der Ausgabe sehen können, wird jedes der Objekte im Array gedruckt, jedoch in umgekehrter Reihenfolge wie bei der normalen schnellen Aufzählung.

Die Speicherverwaltung ist einer der wichtigsten Prozesse in jeder Programmiersprache. Dies ist der Prozess, bei dem der Speicher von Objekten zugewiesen wird, wenn sie benötigt werden, und freigegeben wird, wenn sie nicht mehr benötigt werden.

Das Verwalten des Objektspeichers ist eine Frage der Leistung. Wenn eine Anwendung nicht benötigte Objekte nicht freigibt, wächst der Speicherbedarf und die Leistung leidet.

Objective-C-Speicherverwaltungstechniken können grob in zwei Typen eingeteilt werden.

  • "Manual Retain-Release" oder MRR
  • "Automatische Referenzzählung" oder ARC

"Manual Retain-Release" oder MRR

In der MRR verwalten wir den Speicher explizit, indem wir Objekte selbst verfolgen. Dies wird mithilfe eines Modells implementiert, das als Referenzzählung bezeichnet wird und das die Foundation-Klasse NSObject in Verbindung mit der Laufzeitumgebung bereitstellt.

Der einzige Unterschied zwischen MRR und ARC besteht darin, dass die Aufbewahrung und Freigabe in ersterem von uns manuell erfolgt, während sie in letzterem automatisch erledigt wird.

Die folgende Abbildung zeigt ein Beispiel für die Funktionsweise der Speicherverwaltung in Objective-C.

Der Speicherlebenszyklus des Objekts der Klasse A ist in der obigen Abbildung dargestellt. Wie Sie sehen können, wird die Aufbewahrungsanzahl unter dem Objekt angezeigt. Wenn die Aufbewahrungsanzahl eines Objekts 0 wird, wird das Objekt vollständig freigegeben und sein Speicher wird für andere Objekte freigegeben.

Das Objekt der Klasse A wird zuerst mit der in NSObject verfügbaren Methode alloc / init erstellt. Jetzt wird die Anzahl der Einbehaltungen 1.

Jetzt behält Klasse B das Objekt der Klasse A und die Anzahl der Objekte der Klasse A wird 2.

Dann erstellt Klasse C eine Kopie des Objekts. Jetzt wird es als eine weitere Instanz der Klasse A mit denselben Werten für die Instanzvariablen erstellt. Hier ist die Aufbewahrungszahl 1 und nicht die Aufbewahrungszahl des ursprünglichen Objekts. Dies wird durch die gepunktete Linie in der Figur dargestellt.

Das kopierte Objekt wird von der Klasse C unter Verwendung der Freigabemethode freigegeben, und die Aufbewahrungszahl wird 0, und daher wird das Objekt zerstört.

Im Fall des anfänglichen Objekts der Klasse A beträgt die Anzahl der Zurückbehaltungen 2 und es muss zweimal freigegeben werden, damit es zerstört wird. Dies erfolgt durch Release-Anweisungen der Klassen A und B, die den Retentionszähler auf 1 bzw. 0 verringern. Schließlich wird das Objekt zerstört.

MRR-Grundregeln

  • Wir besitzen jedes Objekt, das wir erstellen: Wir erstellen ein Objekt mit einer Methode, deren Name mit "alloc", "new", "copy" oder "mutableCopy" beginnt.

  • Wir können das Eigentum an einem Objekt übernehmen, indem wir behalten: Ein empfangenes Objekt bleibt normalerweise innerhalb der Methode, in der es empfangen wurde, gültig, und diese Methode kann das Objekt auch sicher an seinen Aufrufer zurückgeben. Wir verwenden Retain in zwei Situationen -

    • Bei der Implementierung einer Accessor-Methode oder einer Init-Methode möchten wir den Besitz eines Objekts übernehmen, das als Eigenschaftswert gespeichert werden soll.

    • Um zu verhindern, dass ein Objekt als Nebeneffekt einer anderen Operation ungültig wird.

  • Wenn wir es nicht mehr benötigen, müssen wir das Eigentum an einem Objekt, das wir besitzen, aufgeben: Wir geben das Eigentum an einem Objekt auf, indem wir ihm eine Freigabemeldung oder eine Autorelease-Nachricht senden. In der Kakao-Terminologie wird das Aufgeben des Eigentums an einem Objekt daher typischerweise als "Freigeben" eines Objekts bezeichnet.

  • Sie dürfen das Eigentum an einem Objekt, das Sie nicht besitzen, nicht aufgeben: Dies ist nur eine Folge der zuvor ausdrücklich festgelegten Richtlinienregeln.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass
- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

- (void)dealloc  {
  NSLog(@"Object deallocated");
  [super dealloc];
}

@end

int main() {
   
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   
   NSLog(@"Retain Count after initial allocation: %d", 
   [sampleClass retainCount]);
   [sampleClass retain];
   
   NSLog(@"Retain Count after retain: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"Retain Count after release: %d", [sampleClass retainCount]);
   [sampleClass release];
   NSLog(@"SampleClass dealloc will be called before this");
   
   // Should set the object to nil
   sampleClass = nil;
   return 0;
}

Wenn wir das obige Programm kompilieren, erhalten wir die folgende Ausgabe.

2013-09-28 04:39:52.310 demo[8385] Hello, World!
2013-09-28 04:39:52.311 demo[8385] Retain Count after initial allocation: 1
2013-09-28 04:39:52.311 demo[8385] Retain Count after retain: 2
2013-09-28 04:39:52.311 demo[8385] Retain Count after release: 1
2013-09-28 04:39:52.311 demo[8385] Object deallocated
2013-09-28 04:39:52.311 demo[8385] SampleClass dealloc will be called before this

"Automatische Referenzzählung" oder ARC

Bei der automatischen Referenzzählung oder ARC verwendet das System dasselbe Referenzzählsystem wie die MRR, fügt jedoch zur Kompilierungszeit die entsprechenden Speicherverwaltungsmethodenaufrufe ein, die für uns erforderlich sind. Wir empfehlen dringend, ARC für neue Projekte zu verwenden. Wenn wir ARC verwenden, ist es normalerweise nicht erforderlich, die in diesem Dokument beschriebene zugrunde liegende Implementierung zu verstehen, obwohl dies in einigen Situationen hilfreich sein kann. Weitere Informationen zu ARC finden Sie in den Versionshinweisen zu ARC.

Wie oben erwähnt, müssen wir in ARC keine Release- und Retain-Methoden hinzufügen, da dies vom Compiler erledigt wird. Tatsächlich ist der zugrunde liegende Prozess von Objective-C immer noch der gleiche. Es verwendet die internen Aufbewahrungs- und Freigabevorgänge, um dem Entwickler das Codieren zu erleichtern, ohne sich um diese Vorgänge kümmern zu müssen, wodurch sowohl die Menge des geschriebenen Codes als auch die Möglichkeit von Speicherverlusten verringert werden.

Es gab ein anderes Prinzip namens Garbage Collection, das in Mac OS-X zusammen mit MRR verwendet wird, aber seit seiner Ablehnung in OS-X Mountain Lion wurde es nicht zusammen mit MRR diskutiert. Außerdem hatten iOS-Objekte nie eine Speicherbereinigungsfunktion. Und mit ARC wird die Garbage Collection auch in OS-X nicht verwendet.

Hier ist ein einfaches ARC-Beispiel. Beachten Sie, dass dies auf dem Online-Compiler nicht funktioniert, da ARC nicht unterstützt wird.

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass
- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

- (void)dealloc  {
  NSLog(@"Object deallocated");
}

@end

int main() {
   /* my first program in Objective-C */
   @autoreleasepool {
      SampleClass *sampleClass = [[SampleClass alloc]init];
      [sampleClass sampleMethod];
      sampleClass = nil;
   }
   return 0;
}

Wenn wir das obige Programm kompilieren, erhalten wir die folgende Ausgabe.

2013-09-28 04:45:47.310 demo[8385] Hello, World!
2013-09-28 04:45:47.311 demo[8385] Object deallocated