56 Stimmen

Ist es in Ordnung, "klassische" malloc()/free() in Objective-C/iPhone-Anwendungen zu verwenden?

Ich habe eine Weile mit der iPhone-Entwicklung herumgespielt, und obwohl es sich ein bisschen umständlich anfühlt, wenn man ein "Hardcore"-.NET-Entwickler ist, ist es gar nicht so schlimm, wenn man sich erst einmal daran gewöhnt hat.

In jedem Buch, das ich über Objective-C lese, ist nur die Rede von retain / release (Referenzzählung) für die Speicherverwaltung. Als altgedienter C/C++-Entwickler kommt es mir seltsam vor, dass die "normale" Zuweisung mit malloc() y free() wird nur in einigen Fußnoten erwähnt.

Ich weiß, dass malloc() y free() Arbeit in Objective-C, aber ich bin neugierig, ob es gängige Praxis ist oder nicht. Immerhin, wenn ich ein Array von 100 Ganzzahlen zuweisen möchten, scheint es, dass dies der effizienteste Weg, es zu tun ist:

int *array = malloc(sizeof(int) * 100);

memset(array,0,sizeof(int) * 100);

// use the array

free(array);

Ist dies tatsächlich der beste Weg, oder sollte ich einfache C-Speicherverwaltung vermeiden?

87voto

Nikolai Ruhe Punkte 80427

Es gibt einen Objective-C-Wrapper um Raw Memory, den ich für ähnliche Aufgaben gerne verwende: NSMutableData . Es hat den Vorteil, dass Sie das Eigentum behalten/freigeben können und das Array leicht wachsen kann (ohne dass Sie die Neuzuweisung selbst vornehmen müssen).

Ihr Code würde wie folgt aussehen:

NSMutableData* data = [NSMutableData dataWithLength:sizeof(int) * 100];
int* array = [data mutableBytes];
// memory is already zeroed

// use the array

// decide later that we need more space:
[data setLength:sizeof(int) * 200];
array = [data mutableBytes]; // re-fetch pointer in case memory needed to be copied

// no need to free
// (it's done when the autoreleased object is deallocated)

47voto

Adam Rosenfield Punkte 373807

Das ist völlig in Ordnung - Objective-C ist eine strenge Obermenge von C, wenn Sie also einfaches C schreiben wollen, hindert Sie nichts daran. In vielen Fällen ist es von Vorteil, wenn man malloc y free um den Overhead der Objective-C-Laufzeit zu vermeiden.

Wenn Sie zum Beispiel ein Array mit einer unbekannten Anzahl von Ganzzahlen dynamisch zuweisen müssen, ist das oft einfacher und leichter:

int *array = malloc(N * sizeof(int));  // check for NULL return value!
// use array[0]..array[N-1]
...
free(array);

Versus:

NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:N];
// use NSMutableArray methods to do stuff with array; must use NSNumbers instead
// of plain ints, which adds more overhead
...
[array release];

Ich habe an einem Wortspiel für das iPhone gearbeitet, und wir mussten ein Multi-Megabyte-Wörterbuch mit gültigen Wörtern laden. Die Wortliste wurde in eine riesige Datei geladen char Array zugewiesen mit malloc() mit einigen cleveren Optimierungen, um die Speichergröße noch weiter zu reduzieren. Offensichtlich ist für so etwas der Overhead der Verwendung einer NSArray ist auf dem begrenzten iPhone völlig unpraktisch. Ich weiß nicht genau, wie hoch der Overhead ist, aber es ist sicherlich mehr als ein Byte pro Zeichen.

5voto

Alex Rozanski Punkte 37585

Natürlich, Sie kann Da Objective-C lediglich eine Obermenge von C ist, kann man diese Funktionen nicht verwenden. Es ist jedoch relativ unüblich, so etwas zu tun, da Objective-C Objekte und Möglichkeiten enthält, die dies erleichtern.

Schließlich könnte man den obigen Code auch so schreiben:

NSMutableArray *array = [[NSMutableArray alloc] init];

//Use the array, adding objects when need be

[array release];

Allerdings müssten Sie die NSNumber Objekte zum Speichern der int s (da NSArray nicht zulässt, dass Nicht-Objekt-Typen hinzugefügt werden), ist es im Allgemeinen üblicher, Objekte zu verwenden, weil es einfacher ist, Daten zu verschieben, und die Array-Klassen sind häufiger mit anderen Cocoa-Klassen integriert, und die Speicherverwaltung ist im Allgemeinen einfacher als die Standard-C-Speicherverwaltung.

Und wenn Sie beginnen, Objekte zum Array hinzuzufügen oder daraus zu entfernen, dann machen die Cocoa-Array-Objekte dies viel einfacher.

3voto

Chuck Punkte 228137

Wenn Sie es mit Standard-C-Typen zu tun haben, ist das nicht weniger üblich oder "OK" als in C. So wird es in C gemacht, das ein Teil von Objective-C ist.

Es ist auch nicht unüblich, eine Art Objekt-Wrapper um diese Dinge zu schreiben, um sie mit dem Rest von Cocoa (KVO, Speicherverwaltung usw.) in Einklang zu bringen. Man könnte also eine IntArray-Klasse erstellen, die das malloc hinter den Kulissen, so dass Sie sie je nach Bedarf aufbewahren und freigeben können. Beachten Sie, dass dies nicht unbedingt notwendig ist - es kann nur praktisch sein, wenn diese Art von Struktur ein Hauptbestandteil Ihres Programms ist.

2voto

Nikolai Ruhe Punkte 80427

Es ist völlig in Ordnung, malloc und free zu verwenden, um Ihre eigene Speicherverwaltung zu machen. Eigentlich ist NSObjects allocWithZone: verwendet malloc, um den Speicher zu erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X