Tạo một mảng số nguyên trong iOS


98

Nếu bạn muốn tạo một mảng các số nguyên, bạn có thể sử dụng NSInteger không? Bạn có phải sử dụng NSNumber không? Nếu vậy, thì tại sao?


Bạn muốn làm gì với mảng số nguyên của mình?
dreamlax

Không chắc. Tôi vừa nghe nói ở đâu đó rằng bạn phải sử dụng NSNumber cho mảng và vì vậy tôi đã tự hỏi về điều đó.
neuromancer

Câu trả lời:


159

Bạn có thể sử dụng một mảng C cũ thuần túy:

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]);

Hoặc, bạn có thể sử dụng dấu NSArrayhoặc NSMutableArray, nhưng ở đây bạn sẽ cần phải gói từng số nguyên bên trong một NSNumbercá thể (vì NSArraycác đối tượng được thiết kế để chứa các cá thể lớp).

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]);

9
Tôi nghĩ rằng điều đáng chú ý là mảng C rất phức tạp đối với bất kỳ thứ gì ngoại trừ việc sử dụng một lần tầm thường, thực sự ít rắc rối hơn khi bọc bất kỳ mảng nào bạn định giữ lại dưới dạng NSArrays của NSNumber.
Chuck

2
Có, và với những tối ưu hóa ở cấp độ chuyên gia [có lẽ là] NSArray, tôi chắc chắn rằng bạn sẽ không cảm thấy hiệu suất bị ảnh hưởng.
dreamlax 27/07/10

@dreamlax Tôi thắc mắc không biết NSArray có loại tối ưu hóa cấp chuyên gia nào không? Phân bổ bộ nhớ thông minh có thể đơn giản là tăng gấp đôi kích thước bộ nhớ được cấp phát khi nó đạt đến giới hạn? :) p
Ben Sinclair

2
@Andy: Hãy xem nguồn thực tế cho CFArray tại đây và kiểm tra các điểm chuẩn tại đây . Nó thông minh hơn một chút so với những gì bạn nghĩ ban đầu.
dreamlax

Giả sử rằng mảng này chỉ được sử dụng trong một phương pháp, không có vấn đề với việc sử dụng một mảng C NSIntegers Chỉ cần đôi kiểm tra ...?
Dan Rosenstark

58

Mảng C:

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

Mảng Objective-C:

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

Mảng Swift:

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

Điều này cũng đúng:

var array = Array(1...10)

NB: mảng được gõ mạnh bằng Swift; trong trường hợp đó, trình biên dịch suy ra từ nội dung rằng mảng là một mảng các số nguyên. Bạn cũng có thể sử dụng cú pháp kiểu rõ ràng này:

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

Nếu bạn muốn có một mảng Đôi, bạn sẽ sử dụng:

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

hoặc là:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type

1
Cú pháp "@number" tương đương cho một số nguyên âm sẽ như thế nào?
Ziofil

5

Nếu bạn muốn sử dụng một NSArray, bạn cần một lớp Objective-C để đưa vào nó - do đó yêu cầu NSNumber.

Điều đó nói rằng, Obj-C vẫn là C, vì vậy bạn có thể sử dụng mảng C thông thường và giữ các số nguyên thông thường thay vì Số NSN nếu bạn cần.


4

Bạn có thể sử dụng CFArray thay vì NSArray. Đây là một bài báo giải thích làm thế nào.

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

Điều tương tự cũng áp dụng cho phiên bản CoreFoundation của các vùng chứa khác.


3
Nếu có lợi thế khi sử dụng CFArray hơn NSArray, tôi không thấy điều đó. NSArray LÀ một CFArray dưới mui xe; đây chỉ là làm một cách khó khăn.
David Gish

1
@Cryptognome có một sự khác biệt nhỏ ở đây, CFArray sẽ không giữ lại hoặc giải phóng bất cứ thứ gì vì nó được tạo mà không có lệnh gọi lại. Tôi đồng ý, mặc dù vậy, dường như không có bất kỳ lợi thế nào.
dreamlax


3

Nếu thứ tự các số nguyên của bạn là không bắt buộc và nếu chỉ có các giá trị duy nhất

bạn cũng có thể sử dụng NSIndexSet hoặc NSMutableIndexSet Bạn sẽ có thể dễ dàng thêm và xóa các số nguyên hoặc kiểm tra xem mảng của bạn có chứa một số nguyên với

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

Kiểm tra tài liệu để biết thêm thông tin.


2
Đó là một ý tưởng khủng khiếp. Đây là một đoạn từ tài liệu của Apple: Bạn không nên sử dụng các bộ chỉ mục để lưu trữ một bộ sưu tập các giá trị số nguyên tùy ý bởi vì bộ chỉ mục lưu trữ các chỉ mục dưới dạng các phạm vi được sắp xếp. Điều này làm cho chúng hiệu quả hơn việc lưu trữ một tập hợp các số nguyên riêng lẻ. Điều đó cũng có nghĩa là mỗi giá trị chỉ mục chỉ có thể xuất hiện một lần trong tập chỉ mục.
Rudolf Adamkovič Ngày

1
Tôi đồng ý và đây là lý do tại sao tôi bắt đầu trả lời của mình với một cảnh báo. Tuy nhiên, tôi biết một số người đã hỏi câu hỏi này về mảng số nguyên và thực sự cần một bộ chỉ mục. Đó là lý do tại sao tôi đưa ra câu trả lời thay thế này.
didier_v_ Ngày

Có gì sai với chỉ một thông thường NSSet(và sử dụng các số nguyên được bao bọc trong một NSNumber)?
dreamlax

@dreamlax overhead, nhưng nói chung, những người hỏi những câu hỏi như vậy không thể xử lý C và họ chỉ đơn giản là có ít số để lưu trữ, vì vậy NSArray hoặc NSSet phải là tốt nhất.
Ben Sinclair

2

Tôi nghĩ việc sử dụng NSNumbers dễ dàng hơn rất nhiều. Tất cả những gì bạn cần làm:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];

nhưng nếu mảng của bạn có 10 hoặc 100 số thì sao?
Henson

1
Bạn có thể sử dụng forhoặc chỉ một mảng khác cho các số và sau đó arrayWithArray.
Neeku
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.