2012-07-25 1 views
1

Мне было интересно, можете ли вы сообщить мне о следующих двух сценариях, которые почти одинаковы, но с небольшими и большими объектами.Правильный способ обработки объектов в цикле с помощью Xcode

Сценарий 1:

В следующем коде:

NSString *iAmAstring; 
for(int i = 0; i < 100000;i++) 
{ 
    NSLog(@"INT VALUE: %d", i); 
    iAmAstring = [NSString stringWithFormat:@"%d", i]; 
    NSLog(@"STRING VALUE: %@", iAmAstring); 
} 

Я сказал, так как я ARC включена нет никаких последствий с делать выше массивную петлю и внутри него для каждого loop running Я выделяю и инициализирую указатель на строку. Потому что мне сказали, что он слишком мал и не имеет значения, и ARC может справиться с этим. Но не делать этого с большими объектами. Я изначально из C# фона, и я привык устанавливать даже мою строку в конце цикла к нулевому значению, но здесь вы не можете отпустить его в конце цикла, потому что ARC будет жаловаться, и мне сказали, если я установил его на nil на конец цикла я бы создавал больше работы для ARC, и я не очень хорошо делаю и создаю зомби-код. Может ли кто-то уточнить, что они будут делать с объектом, который они выделяют, инициализируя массивный цикл, который мал по размеру памяти (предпочтительно строка, которую я использовал), когда ARC включается, в конце цикла?

Сценарий 2:

То же самое, что и выше, но предположим теперь, NSString то будет быть использованы выше, теперь другой объект, который является большим по размеру. Здесь я бы выделил &, чтобы инициализировать его перед циклом, а затем использовать его в цикле, установив его, но как бы я снова сделал кое-что для него в конце цикла, чтобы получить его бесплатно, поэтому снова ARC включился?

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

ответ

4

В ARC вы определяете свои пулы авторефератов с помощью блоков @autoreleasepool {}. Эти блоки создают новые пулы автореализованных объектов и сбрасывают их, когда объем блока заканчивается.

NSString *iAmAstring; 
for(int i = 0; i < 100000;i++) 
{ 
    @autoreleasepool { 
     NSLog(@"INT VALUE: %d", i); 
     iAmAstring = [NSString stringWithFormat:@"%d", i]; 
     NSLog(@"STRING VALUE: %@", iAmAstring); 
    } 
} 

Это приведет к утечке пула авторефератов и освобождению всех объектов с автореализацией на каждой итерации цикла. Это расточительное отношение к крошечным струнам, но это может оказать большую помощь с более крупными объектами.

Быстрое примечание о том, как работает автореферат: все, что он делает, дает вам дополнительные призывы к release, когда бассейн слит. Пул по умолчанию сбрасывается в цикле событий (т. Е. Через некоторое время после выхода вашего метода). Пулы, созданные вручную, сливаются, когда заканчивается область @autoreleasepool.

Я родом из C# фоне, и я привык к установке даже мои строки в конце цикла обнулить

Если вы не повторно использовать переменную позже, это добавляет совершенно бесполезные линии кода в вашу программу: компилятор C# уже достаточно умен в течение некоторого времени, чтобы выяснить самый ранний момент, чтобы сделать ваши объекты доступными для сбора мусора, поэтому назначения null не помогают.

0

Что я никогда не понимаю, так это то, почему люди думают, что им нужно использовать пул автозапуска вместо того, чтобы просто использовать alloc/init для создания своих объектов и явного релиза, чтобы избавиться от них.

Есть несколько объектов, которые имеют побочные эффекты, требующие autorelease бассейн (финики, я смотрю на вас), но по большей части, делая

{ 
    NSString *s = [[NSString alloc] initWithFormat:...]; 
    .... 
    [s release]; 
} 

в цикле будет более эффективно, чем полагаться на автореферат.

Что касается сценария 2, извините, NSString является неизменным - вы не меняете свои значения.