Могу ли я назначить размер массива с помощью NSMutableArray? - PullRequest
4 голосов
/ 06 апреля 2010

Раньше я был программистом на Java, который массив должен объявлять в первый раз, например:

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

Я не знаю, дают ли мне Objective C, NSMutableArray эту способность или нет. На самом деле, я хочу сделать массив 10 * 10. это заранее. Я пытаюсь сделать это:

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

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

Но возникает ошибка, сообщающая о моем несовместимом присваивании типов.

Ответы [ 8 ]

10 голосов
/ 06 апреля 2010
  1. Поле производительности редко используется. В любом случае массив будет расширен по требованию.

  2. И поле емкости просто сообщает массиву, сколько памяти вы можете использовать. Длина массива по-прежнему равна 0.

  3. Но вы можете вырастить массив из пустого:

     for (int i = 0; i < 10; ++ i)
         [myArray addObject:…];
    
  4. Для чтения и записи в элемент NSMutableArray вам необходимо:

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

    Вы не можете напрямую подписать NSArray.

  5. Ваш код имеет утечку памяти. В отличие от Java, ObjC не использует GC, если вы явно не включили его (а ObjC на iPhoneOS не имеет GC). ObjC управляет памятью путем ручного подсчета ссылок . По сути, вам нужно убедиться, что количество ссылок на вещи, которыми вы не владеете, не изменяется в процессе. Подробнее см. http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html.

    В вашем случае [[NSMutableArray alloc] …]; создает объект с номером ссылки +1, затем присвоение принимает массив, это означает, что вы больше не являетесь его владельцем, но количество ссылок не сбалансировано до 0, поэтому эта память не будет должным образом освобождена. Вам нужно использовать удобные методы, такие как [NSMutableArray array…], чтобы создать объект с номером счета 0.

  6. NSArray может хранить только объекты ObjC. int в C (ObjC) является примитивом и не может быть сохранен в NSArray. Вы должны вставить в NSNumber на [NSNumber numberWithInt:0]. Вы можете вернуть целое число с помощью -intValue.

  7. В заключение, ваш код необходимо изменить следующим образом:

      -(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. Но ObjC - это расширенный набор C. Вы можете просто использовать простой массив 10x10 C.

    int arr[10][10];
    
1 голос
/ 06 апреля 2010

Вы хотите массив 10х10 - чего?

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

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

но встречаются ошибки, рассказывающие мои несовместимое присвоение типа.

Потому что вы не можете присвоить myArray таким образом. myArray - это объект , представляющий структуру данных массива . Это , а не массив C.

Если вам нужен массив 10x10 с примитивным типом данных, вы можете объявить его так же, как в C:

int myArray[10][10];
0 голосов
/ 23 ноября 2014

Вы можете использовать следующий код для изменения размера NSMutableArray после его создания:

@interface NSMutableArray (Resizing)
- (NSMutableArray *)resize:(NSInteger)newSize;
@end

@implementation NSMutableArray (Resizing)
- (NSMutableArray *)resize:(NSInteger)newSize
{
    int size = (newSize > [self count]) ? self.count : newSize;
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
    for (int i = 0; i < size; i++){
        [array addObject:[self objectAtIndex:i]];
    }   
    return array;
}
@end
0 голосов
/ 06 апреля 2010

Есть два способа сделать это.

Обычный старый C

Если вы хотите хранить объекты, вы должны использовать тип id вместо int.

int myarray[10][10];
myarray[5][2] = 412;

Objective-C

NSArray не предназначены для того, чтобы иметь пробелы без объектов, если вы нуждаетесь в них, вы можете использовать [NSNull null], но если это так, то массив C будет лучше в любом случае.1013 *

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

for (int i=0; i < 10; i++) {
    NSMutableArray *innerArray = [[NSMutableArray alloc] initWithCapacity:10];
    for (int j=0; j < 10; j++) {
        [innerArray addObject:[NSNull null]];
    }
    [myArray addObject:innerArray];
    [innerArray release];
}

[[myArray objectAtIndex:5]
      replaceObjectAtIndex:2 withObject:[NSNumber numberWithInteger:123]];
0 голосов
/ 06 апреля 2010

Вы не можете получить доступ к объектам массива Какао с помощью скобок. Ваш второй бит кода должен быть:

NSMutableArray *myArray = [[NSmutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i++) {
    [myArray insertObject:[NSMutableArray arrayWithCapacity:10] atIndex:i];    // Note: not using myArray[i]!
}
0 голосов
/ 06 апреля 2010

NSArray объекты имеют фиксированный размер, который невозможно изменить после инициализации. NSMutableArray объекты могут изменить размер. Массив 10 × 10 иногда реализуется как NSArray, содержащий 10 отдельных NSArray объектов, каждый из которых содержит десять элементов. Это быстро становится громоздким, иногда проще прибегнуть к простой C для такой задачи:

int tenByTen[10][10];

Или вы можете использовать это:

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

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

Тогда вы могли бы сделать:

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

И вы также можете вернуть их из методов:

- (TenByTen) mangleTenByTen:(const TenByTen) input
{
    TenByTen result = input;
    result.x[1].y[4] = 10000;
    return result;
}
0 голосов
/ 06 апреля 2010

initWithCapacity: это то, что вы хотите. Это может выглядеть как

NSMutableArrat *array = [[NSMutableArray alloc] initWithCapacity:10];
0 голосов
/ 06 апреля 2010

Требуется NSMutableArray + arrayWithCapacity:

Обратите внимание, что установка начальной емкости является просто оптимизацией - изменяемые массивы расширяются по мере необходимости.

EDIT: Для дела 10х10,

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

Примечания:

  • массив сохраняет добавленные к нему объекты, поэтому нет необходимости сохранять subArray
  • только объекты (не примитивные типы, такие как "int") могут быть добавлены в NSArray, следовательно, требуется NSNumber numberWithInt:
  • вы используете такие методы, как objectAtIndex: и replaceObjectAtIndex:withObject:, чтобы получить / установить значение из NSArray, а не синтаксиса массива ([])

См. Ссылки Apple для NSArray и NSMutableArray

...