4 Stimmen

Kann ich Array Größe mit NSMutableArray zuweisen?

Ich war früher ein Java-Programmierer, der das Array das allererste Mal deklarieren muss, wie hier:

int[] anArray;              // declares an array of integers
anArray = new int[10];      // allocates memory for 10 integers

Ich weiß nicht, ob die Objective C, NSMutableArray auch geben mir diese Fähigkeit oder nicht. Eigentlich möchte ich ein 10*10 Array machen. thz im Voraus. Ich versuche, dies zu tun:

myArray = [[NSMutableArray alloc] initWithCapacity:10]; 

for (int i=0; i<10; i++) {
    myArray[i] = [[NSMutableArray alloc] initWithCapacity:10]; 
}

Aber es treten Fehler auf, die mir eine inkompatible Typzuweisung melden.

10voto

kennytm Punkte 488916
  1. Das Kapazitätsfeld ist nur selten nützlich. Das Array wird ohnehin bei Bedarf erweitert.

  2. Und das Kapazitätsfeld teilt dem Array lediglich mit, wie viel Speicher Sie verwenden können. Die Länge des Arrays ist immer noch 0.

  3. Aber Sie können das Array von leer aus erweitern:

     for (int i = 0; i < 10; ++ i)
         [myArray addObject:…];
  4. Um ein Element in einem NSMutableArray zu lesen und zu beschreiben, benötigen Sie:

     id x = [array objectAtIndex:i];              // x = array[i];
     [array replaceObjectAtIndex:i withObject:y]; // array[i] = y;

    Sie kann nicht ein NSArray direkt subscriptieren.

  5. Ihr Code hat ein Speicherleck. Im Gegensatz zu Java verwendet ObjC keine GC, es sei denn, Sie aktivieren sie explizit (und ObjC auf iPhoneOS hat keine GC). ObjC verwaltet Speicher durch manuelle Referenzzählung . Grundsätzlich müssen Sie sicherstellen, dass sich die Anzahl der Sachen, die Sie nicht besitzen, nicht ändert. Siehe http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html für Details.

    In Ihrem Fall, [[NSMutableArray alloc] …]; ein Objekt mit ref count +1 erzeugt, übernimmt die Zuweisung das Array, d.h. Sie besitzen es nicht mehr, aber der ref count ist nicht auf 0 ausgeglichen, so dass dieser Speicher nicht ordnungsgemäß freigegeben wird. Sie müssen bequeme Methoden verwenden wie [NSMutableArray array…] um ein Objekt mit der Referenznummer 0 zu erstellen.

  6. NSArray's können nur ObjC-Objekte speichern. int in C (ObjC) ist ein Primitivum und kann nicht in einem NSArray gespeichert werden. Sie müssen Box es in eine NSNummer von [NSNumber numberWithInt:0] . Sie können die ganze Zahl zurückbekommen mit -intValue .

  7. Abschließend muss Ihr Code wie folgt geändert werden:

      -(NSMutableArray*)get10x10Array {
         NSMutableArray* arr = [NSMutableArray array];
         for (int i = 0; i < 10; ++ i) {
            NSMutableArray* subarr = [NSMutableArray array];
            for (int j = 0; j < 10; ++ j)
               [subarr addObject:[NSNumber numberWithInt:0]];
            [arr addObject:subarr];
         }
         return arr;
      }
  8. Aber ObjC ist eine Obermenge von C. Sie können einfach ein einfaches 10x10 C-Array verwenden.

    int arr[10][10];

5 Stimmen

Ich stimme nicht zu, dass "das Kapazitätsfeld nur selten nützlich ist". In praktisch jeder Sprache mit veränderlichen, dynamisch wachsenden Sammlungen, die durch zusammenhängenden Heap-Speicher unterstützt werden, gilt es als bewährte Praxis und als Optimierung, solche Sammlungen mit einer Kapazität zuzuweisen, wenn man weiß oder abschätzen kann, wie groß sie sein werden. Dies hilft zu vermeiden, dass der Sicherungsspeicher neu zugewiesen werden muss, wenn eine Sammlung über diesen Wert hinaus wächst. Ein einfaches Beispiel: Wenn Sie ein C-Array in ein NSMutableArray kopieren wollen, sollten Sie das NSMutableArray mit einer Kapazität initialisieren, die mindestens so groß ist wie die Elemente des C-Arrays.

1voto

Shaggy Frog Punkte 27326

Sie wollen ein 10x10 Feld - von was?

myArray = [[NSMutableArray alloc] initWithCapacity:10]; 

for (int i=0; i<10; i++) {
    myArray[i] = [[NSMutableArray alloc] initWithCapacity:10]; 
}

Aber es treten Fehler auf, die mir sagen inkompatible Typenzuweisung.

Weil Sie nicht zuordnen können myArray so. myArray ist eine Objekt die eine Array-Datenstruktur darstellt . Es ist pas ein C-Array.

Wenn Sie ein 10x10-Array eines primitiven Datentyps benötigen, können Sie es wie in C deklarieren:

int myArray[10][10];

1 Stimmen

Wahrscheinlich möchten Sie die Arrays, die Sie innerhalb der Schleife erstellen, automatisch freigeben (oder Sie verwenden arrayWithCapacity: anstelle von alloc / initWithCapacity ), um ein Speicherleck zu vermeiden.

0 Stimmen

Nun, natürlich. Was ich getan habe, war zitiert nach den Text des Auftraggebers, ohne dass er vorschlägt, es auf diese Weise zu tun.

0voto

David Gelhar Punkte 27707

Sie wollen NSMutableArray +arrayWithCapacity:

Beachten Sie, dass die Festlegung der Anfangskapazität lediglich eine Optimierung darstellt - veränderbare Arrays lassen sich nach Bedarf erweitern.

EDIT: Um den 10x10 Fall zu machen,

myArray = [[NSMutableArray alloc] initWithCapacity:10]; 

for (int i=0; i<10; i++) {
    NSMutableArray *subArray = [NSMutableArray arrayWithCapacity:10];
    [myArray addObject:subArray];
    for (int j = 0; j<10; j++) {
          [subArray addObject:[NSNumber numberWithInt:0]];
    }
}

Notes :

  • ein Array behält die ihm hinzugefügten Objekte bei, so dass es nicht notwendig ist, sie zu behalten subArray
  • nur Objekte (keine primitiven Typen wie "int") zu einem NSArray hinzugefügt werden können, daher die Notwendigkeit für NSNumber numberWithInt:
  • verwenden Sie Methoden wie objectAtIndex: y replaceObjectAtIndex:withObject: um einen Wert aus einem NSArray zu erhalten/zu setzen, nicht in der Syntax für Array-Teilzeichen ([])

Siehe Apple-Referenzen für NSArray y NSMutableArray

0 Stimmen

Ich möchte nur die feste Größe, sie ist für meine Anwendung gerade richtig.

0 Stimmen

Oder, abhängig von der Lebensdauer des Arrays, können Sie die von @zonble vorgeschlagene Lösung alloc / initWithCapacity verwenden. Der Unterschied ist, dass die +arrayWithCapacity: Convenience-Methode ein automatisch freigegebenes Objekt zurückgibt.

0 Stimmen

Das Array bleibt erhalten, bis der Benutzer die Anwendung beendet.

0voto

zonble Punkte 4203

InitWithCapacity: ist das, was Sie wollen. Es könnte wie folgt aussehen

NSMutableArrat *array = [[NSMutableArray alloc] initWithCapacity:10];

0 Stimmen

Sorry, ich kann etwas in meinem Beispiel zu verpassen, ich brauche ein 10 * 10 Array, so, ich nur erste Zuweisung der *array mit einer Kapazität und Schleifen jede Zeile zu füllen?

0voto

dreamlax Punkte 91447

NSArray Objekte haben eine feste Größe, die nach ihrer Initialisierung nicht mehr verändert werden kann. NSMutableArray Objekte können ihre Größe ändern. Ein 10×10 Array wird manchmal als ein NSArray mit 10 einzelnen NSArray Objekte, von denen jedes zehn Gegenstände enthält. Das wird schnell umständlich, manchmal ist es einfacher, für eine solche Aufgabe auf einfaches C zurückzugreifen:

int tenByTen[10][10];

Oder Sie können dies verwenden:

typedef struct
{
    int y[10];
} TenInts;

typedef struct
{
    TenInts x[10];
} TenByTen;

Dann könnten Sie das tun:

- (void) doSomethingWithTenByTen:(const TenByTen) myMatrix
{
    NSLog ("%d", myMatrix.x[1].y[5]);
}

Und man kann sie auch aus Methoden zurückgeben:

- (TenByTen) mangleTenByTen:(const TenByTen) input
{
    TenByTen result = input;
    result.x[1].y[4] = 10000;
    return result;
}

0 Stimmen

Es spielt keine Rolle, eine feste Größe Array ist ok für meinen Fall.

0 Stimmen

Aber das NSArray scheint keine initWithCapacity-Methode zu haben.

0 Stimmen

Richtig, initWithCapacity ist nur für NSMutableArray. Es macht keinen Sinn, von der "Kapazität" eines NSArray zu sprechen, da sie sich nicht mehr ändern kann, sobald sie erstellt wurde

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