2010-10-07 2 views
4

Я все еще обертывание моей головы вокруг некоторых нюансов управления памятью в Objective-C, и придумал следующий случай я не уверен насчет:Уменьшение объема памяти функции с множеством автореализованных переменных?

+ (NSDecimalNumber*)factorial: (NSDecimalNumber *)l { 

    NSDecimalNumber *index = l; 
    NSDecimalNumber *running = [NSDecimalNumber one]; 

    for (; [index intValue] > 1; index = [index decimalNumberBySubtracting:[NSDecimalNumber one]]) { 
     running = [running decimalNumberByMultiplyingBy: index]; 
    } 
    return running; 
} 

Здесь decimalNumberByMultiplyingBy и decimalNumberBySubtracting будут создание много NSDecimalNumbers, которые в конечном итоге получат автореализацию, поскольку я это понимаю, но до тех пор я беспокоюсь, что содержащаяся программа будет висящей до огромного количества памяти.

Должен ли я когда-нибудь вводить пул авторефератов? (Если это где?) Это будет иметь заметное влияние на производительность (по сравнению с побочным эффектом использования большого количества памяти)?

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

Это, вероятно, вопрос n00b, но я пытаюсь получить аромат, для которого лучшая практика (ы) есть/находятся в этой ситуации.

+0

Примечание: Я понимаю, что это не будет суперэффективным методом для расчета факториалов из-за ограничений диапазона NSDecimalNumber, только что появившихся в моей голове для примера. –

ответ

5

Рекомендуется избегать создания множества крупных объектов с автореализацией в течение одного прохода цикла цикла. Вы уже знаете о решениях. Вы можете использовать неавтореализованные объекты и освобождать их, когда закончите с ними. Вы также можете создать пул автозапуска для разделов вашего кода, которые создают большое количество объектов с автореализацией. Когда объект автореализован, он освобождается, когда пул резервирования авторезистов освобождается/сливается. Использование autorelease бассейн будет выглядеть следующим образом:

NSAutoReleasePool *subPool = [[NSAutoreleasePool alloc] init]; 
// Code that generates a bunch of autoreleased objects. 
[subPool release]; 

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

Ознакомьтесь с руководством по программированию памяти Apple для управления какао для получения более подробной информации.

+0

Я правильно понимаю, что не могу вручную освобождать объекты, созданные decimalNumberBySubtracting? Это приведет к возникновению проблемы, когда создаваемые объекты будут автореализованы? –

+0

Да. Единственный способ «вручную освободить» объекты, которые уже были автореализованны, - использовать пул автозаполнения, как показывает пример кода. –

+0

Вы правы. Если вы не являетесь владельцем объекта, его не следует отпускать. Пул автозапуска освободит объект, поэтому, если вы его выпустите, он в конечном итоге будет выпущен дважды. –

1

Лучший способ определить ответ - написать его несколькими различными способами и испытать. Я не думаю, что это будет проблемой, но NSDecimalNumbers собираются max ~ 100 !, а 100 объектов NSDecimalNumber, вероятно, не будут иметь большого значения.


Ответ на другие вопросы: В ситуациях, когда это имеет значение, вы можете вручную освободить свои объекты. Вы также можете создать пул автозапуска в этом цикле. Autorelease is super fast.

while(/*condition*/) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    // code goes here 

    [pool drain]; 
} 
1

Вы можете настроить пул автозапуска в пределах цикла, но зачем беспокоиться?

Вы не собираетесь быть в состоянии накопить, что многие объекты в этом цикле, потому что вы вычисления факториала, и самый большой показатель NSDecimalNumber может иметь 127.

Вы получите ошибку переполнения перед вы даже получаете до 100 итераций через цикл.

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

Смежные вопросы