Подтвердить что ты не робот

Можно ли использовать "classic" malloc()/free() в приложениях Objective-C/iPhone?

Некоторое время я играл с разработкой для iPhone, и, хотя вы чувствуете себя немного неловко, когда вы являетесь "заядлым" разработчиком .NET, не так уж и плохо, когда вы привыкнете к нему.

В каждой книге, которую я читал об Objective-C, говорится только о retain/release (подсчет ссылок) для управления памятью. Как разработчик C/C++ из старой школы, кажется странным, что выделение "нормального" пути с использованием malloc() и free() упоминается только в некоторых сносках.

Я знаю, что malloc() и free() работают в Objective-C, но мне любопытно, является ли это обычной практикой или нет. В конце концов, если я хочу выделить массив из 100 целых чисел, кажется, что это самый эффективный способ сделать это:

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

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

// use the array

free(array);

Это действительно лучший способ, или мне следует избегать простого управления памятью на C?

4b9b3361

Ответ 1

Там Objective-C обертка вокруг необработанной памяти, которую я люблю использовать для подобных задач: NSMutableData. Это дает вам преимущество в том, что вы сохраняете/освобождаете право собственности, а также можете легко вырастить массив (без необходимости самостоятельно выполнять перераспределение).

Ваш код будет выглядеть так:

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 done when the autoreleased object is deallocated)

Ответ 2

Это отлично - Objective-C является строгим надмножеством C, поэтому, если вы хотите написать обычный C, ничего не мешает вам это сделать. Во многих случаях выгодно использовать malloc и free, чтобы избежать накладных расходов на время выполнения Objective-C.

Например, если вам необходимо динамически выделять массив неизвестного числа целых чисел, это часто проще и проще:

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

Я работал над текстовой игрой для iPhone, и нам пришлось загрузить многомесячный словарь действительных слов. Список слов был загружен в один гигантский массив char, выделенный с помощью malloc(), с некоторыми умными оптимизациями, чтобы еще больше уменьшить размер памяти. Очевидно, что что-то вроде этого, накладные расходы на использование NSArray полностью нецелесообразны для ограниченного iPhone. Я не знаю точно, что такое накладные расходы, но это, конечно, более одного байта на каждого персонажа.

Ответ 3

Конечно, вы можете использовать эти функции, потому что Objective-C является просто супермножеством C. Однако довольно редко это делать, поскольку Objective-C содержит объекты и способы сделать это проще.

В конце концов, вы можете написать код выше:

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

//Use the array, adding objects when need be

[array release];

Хотя вам нужно было бы создать объекты NSNumber для хранения int (так как NSArray не позволяет добавлять не-объекты), обычно чаще используется объект, потому что это проще для перемещения данных вокруг, а классы массивов интегрируются чаще с другими классами Cocoa, а управление памятью обычно более прямолинейно, чем стандартное управление памятью.

Кроме того, если вы начинаете добавлять или удалять объекты из массива, объекты массива Cocoa делают это намного проще.

Ответ 4

Если вы имеете дело со стандартными типами C, это не менее распространено или "ОК", чем в C. То, как это делается на C, которое является частью Objective-C.

Также необычно писать какую-то обертку объектов вокруг этих вещей, чтобы привести ее в гармонию с остальной частью Cocoa (KVO, управление памятью и т.д.). Таким образом, вы можете создать класс IntArray, который выполняет malloc ing за кулисами, чтобы вы могли сохранить и освободить его по мере необходимости. Обратите внимание, что это не является абсолютно необходимым - это может быть удобно, если такая структура является основной частью вашей программы.

Ответ 5

Совершенно прекрасно использовать malloc и свободно выполнять собственное управление памятью. На самом деле NSObject allocWithZone: использует malloc для получения памяти.