Erstellen eines Arrays von Ganzzahlen in iOS

98

Wenn Sie ein Array von Ganzzahlen erstellen möchten, können Sie NSInteger verwenden? Müssen Sie NSNumber verwenden? Wenn ja, warum dann?

Neuromant
quelle
Was möchten Sie mit Ihrem Array von Ganzzahlen tun?
Dreamlax
Nicht sicher. Ich habe gerade irgendwo gehört, dass Sie NSNumber für Arrays verwenden müssen, und deshalb habe ich mich darüber gewundert.
Neuromancer

Antworten:

159

Sie können ein einfaches altes C-Array verwenden:

NSInteger myIntegers[40];

for (NSInteger i = 0; i < 40; i++)
    myIntegers[i] = i;

// to get one of them
NSLog (@"The 4th integer is: %d", myIntegers[3]);

Oder Sie können ein NSArrayoder verwenden NSMutableArray, aber hier müssen Sie jede Ganzzahl in einer NSNumberInstanz einschließen (da NSArrayObjekte für Klasseninstanzen ausgelegt sind).

NSMutableArray *myIntegers = [NSMutableArray array];

for (NSInteger i = 0; i < 40; i++)
    [myIntegers addObject:[NSNumber numberWithInteger:i]];

// to get one of them
NSLog (@"The 4th integer is: %@", [myIntegers objectAtIndex:3]);

// or
NSLog (@"The 4th integer is: %d", [[myIntegers objectAtIndex:3] integerValue]);
Dreamlax
quelle
9
Ich denke, es ist erwähnenswert, dass C-Arrays für alles andere als eine triviale, einmalige Verwendung so problematisch sind, dass es tatsächlich weniger schwierig ist, Arrays zu verpacken, die Sie als NSArrays von NSNumber behalten möchten.
Chuck
2
Ja, und angesichts der [vermutlich] Optimierungen auf Expertenebene unter der Haube von NSArray, bin ich sicher, dass Sie den Leistungseinbruch nicht spüren werden.
Dreamlax
@dreamlax Ich frage mich, welche Art von Optimierung auf Expertenebene unter der Haube von NSArray steckt. Intelligente Speicherzuweisung, die wahrscheinlich die Größe des zugewiesenen Speichers verdoppelt, sobald er das Limit erreicht?
Ben Sinclair
2
@Andy: Sehen Sie sich hier die aktuelle Quelle für CFArray an und sehen Sie sich hier die Benchmarks an . Es ist ein bisschen schlauer als man zunächst denkt.
Dreamlax
Angenommen, dieses Array wird nur innerhalb einer Methode verwendet, gibt es keine Probleme bei der Verwendung eines C-Arrays von NSIntegern? Nur eine doppelte Überprüfung ...
Dan Rosenstark
58

C-Array:

NSInteger array[6] = {1, 2, 3, 4, 5, 6};

Objective-C-Array:

NSArray *array = @[@1, @2, @3, @4, @5, @6];
// numeric values must in that case be wrapped into NSNumbers

Swift Array:

var array = [1, 2, 3, 4, 5, 6]

Das ist auch richtig:

var array = Array(1...10)

NB: Arrays sind stark in Swift typisiert. In diesem Fall schließt der Compiler aus dem Inhalt, dass das Array ein Array von Ganzzahlen ist. Sie können auch diese explizite Syntax verwenden:

var array: [Int] = [1, 2, 3, 4, 5, 6]

Wenn Sie eine Reihe von Doppel möchten, würden Sie verwenden:

var array = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] // implicit type-inference

oder:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type
Frédéric Adda
quelle
1
Was wäre die äquivalente "@number" -Syntax für eine negative Ganzzahl?
Ziofil
5

Wenn Sie ein NSArray verwenden möchten, benötigen Sie eine Objective-C-Klasse, um es einzufügen - daher die NSNumber-Anforderung.

Das heißt, Obj-C ist immer noch C, sodass Sie bei Bedarf reguläre C-Arrays verwenden und reguläre Ints anstelle von NSNumbers speichern können.

Dennis Munsie
quelle
4

Sie können CFArray anstelle von NSArray verwenden. Hier ist ein Artikel, der erklärt, wie.

CFMutableArrayRef ar = CFArrayCreateMutable(NULL, 0, NULL);
for (NSUInteger i = 0; i < 1000; i++)
{
  CFArrayAppendValue(ar, (void*)i);
}
CFRelease(ar); /* Releasing the array */

Gleiches gilt auch für die CoreFoundation-Version der anderen Container.

coyotte508
quelle
3
Wenn die Verwendung von CFArray gegenüber NSArray einen Vorteil hat, sehe ich das nicht. Ein NSArray ist ein CFArray unter der Haube; das macht es einfach auf die harte Tour.
David Gish
1
@Cryptognome Hier gibt es einen kleinen Unterschied. Das CFArray behält nichts bei oder gibt nichts frei, da es ohne Rückruf erstellt wurde. Ich stimme jedoch zu, es scheint keinen Vorteil zu geben.
Dreamlax
3

Wenn die Reihenfolge Ihrer Ganzzahlen nicht erforderlich ist und nur eindeutige Werte vorhanden sind

Sie können auch NSIndexSet oder NSMutableIndexSet verwenden. Sie können ganz einfach Ganzzahlen hinzufügen und entfernen oder prüfen, ob Ihr Array eine Ganzzahl mit enthält

- (void)addIndex:(NSUInteger)index
- (void)removeIndex:(NSUInteger)index
- (BOOL)containsIndexes:(NSIndexSet *)indexSet

Weitere Informationen finden Sie in der Dokumentation .

didier_v_
quelle
2
Das ist eine schreckliche Idee. Hier ist ein Teil aus Apples Dokumentation: Sie sollten keine Indexsätze verwenden, um eine beliebige Sammlung von Ganzzahlwerten zu speichern, da Indexsätze Indizes als sortierte Bereiche speichern. Dies macht sie effizienter als das Speichern einer Sammlung einzelner Ganzzahlen. Dies bedeutet auch, dass jeder Indexwert nur einmal im Indexsatz angezeigt werden kann.
Rudolf Adamkovič
1
Ich stimme zu und deshalb habe ich meine Antwort mit einer Warnung begonnen. Ich kenne jedoch einige Leute, die diese Frage zu Integer-Arrays gestellt haben und tatsächlich einen Indexsatz benötigten. Deshalb habe ich diese alternative Antwort gegeben.
Didier_v_
Was ist falsch an einer regulären NSSet(und der Verwendung von Ganzzahlen, die in eine eingeschlossen sind NSNumber)?
Dreamlax
@dreamlax Overhead, aber im Allgemeinen können Leute, die solche Fragen stellen, nicht mit C umgehen und sie haben einfach nur wenige Nummern zu speichern, daher müssen NSArray oder NSSet die besten sein.
Ben Sinclair
2

Ich denke, es ist viel einfacher, NSNumbers zu verwenden. Das alles was Sie tun müssen:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];
Neeku
quelle
aber was ist, wenn Ihr Array 10 oder 100 Zahlen hat?
Henson
1
Sie können foroder nur ein anderes Array für die Zahlen verwenden, und dann arrayWithArray.
Neeku