Как бороться с управлением памятью при инициализации NSArray из массива C - PullRequest
0 голосов
/ 14 марта 2011

Я инициализирую NSArray, используя массив C объектов, которые я динамически создаю:

MyClass *initArray [dynamicSize];

for (NSUInteger i=0; i<dynamicSize; i++) {
   initArray [i] = [[MyClass alloc] initWithSomthingDependingOn: i];
}
// At this point, initArray contains objects with retainCount == 1

classObjectArray = [[NSArray alloc] initWithObjects:initArray count:dynamicSize];
// And... at this point, retainCount == 2

Моя проблема / сомнение в том, как бороться с управлением памятью в этой ситуации. Насколько я понимаю, я должен выпустить все объекты один раз, чтобы сохранить retainCount == 1, потому что я буду хранить только одну ссылку на них (initArray исчезнет после возврата из функции) ... но я считаю неэффективным повторение через массив только для этого.

Есть предложения?

Заранее спасибо

Редактировать: , чтобы избежать путаницы Пример изменения кода: initExpresion (i) на [[MyClass alloc] initWith... ] , который лучше отражает природу проблемы.

Ответы [ 2 ]

1 голос
/ 14 марта 2011

Есть предложения?

Да.

Не звоните retainCount

В лучшем случае вводит в заблуждение и в большинстве случаев совершенно бесполезно.

Как сказал Джонатан, вы сохраняете только баланс, который вы вызываете с помощью различных перечисленных методов. То есть обрабатывает счет удержания как дельта . Если вы увеличите его, вы должны уменьшить его.

В этом конкретном случае «initExpression()» возвращает либо сохраненный, либо автоматически освобожденный объект. Вы не можете узнать с помощью retainCount, поскольку autorelease не сразу уменьшает этот счет (это, по сути, задержка release).

(Нет, initExpression() не перепутал вопрос или этот ответ - retainCount бесполезен для "обнаружения" автоматически выпущенного объекта.)

В комментарии вы сказали:

Я обеспокоен влияние на производительность любого автоматическое освобождение объектов или итерация снова через массив, чтобы отправить отправить сообщение всем объектам.

Обеспокоены тем, что вы измерили проблему или потому, что кажется, что это может быть проблемой?

Не тратьте время на исправление проблем с производительностью, которые не были определены количественно. Крайне маловероятно, что объекты, выпущенные вручную или автоматически выпущенные, будут проблемой в этом контексте. Это может произойти, но только если у вас нет N тысяч объектов (в этот момент у вас может возникнуть проблема с памятью), или вы много раз вызываете этот код.

Предложение Джонатана полностью отказаться от массива C!

0 голосов
/ 14 марта 2011

initExpression() должен автоматически высвобождать свои результирующие объекты, поскольку его имя не начинается с retain, create, new, copy или alloc.Если это произойдет, проблема исчезнет.

Если возвращаемые объекты не автоматически высвобождаются, то вызывающая сторона (ваша) несет ответственность за releas или autorelease этих объектов после их использования.

Редактировать: Конечно, вы можете просто пропустить массив C и использовать NSMutableArray с емкостью dynamicSize:

NSMutableArray *classObjectArray = [NSMutableArray arrayWithCapacity: dynamicSize];
for (NSUInteger i = 0; i < dynamicSize; i++) {
    id myObject = [[MyClass alloc] init...];
    if (myObject) {
        [classObjectArray addObject: myObject];
        [myObject release];
    }
}
...