0

Я столкнулся с проблемой, которая, как кажется, называется «тонет» в пулах автообновлений.Autorelease Drowning

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

2 вопросы:

  1. Так как я не использую методы класса AT ALL - это то, что окончательное решение, или, несмотря на это, будут некоторые методы экземпляра (Foundation, UIKit) еще autorelease объекты без моего зная об этом?

  2. или я могу выделить пул автоопределений до вызова методов класса и слить его после вызова методов класса - будет ли это постоянным решением?

ответ

2
  1. Просто потому, что вы не используете метод класса не означает, что вы собираетесь избежать autoreleased объектов. Например: NSString * path = [anotherString stringByAppendingPathComponent:@"foo"] возвращает объект с автореализацией, но методы класса не были задействованы. Насколько я знаю, единственный способ избежать автореализованных объектов - не использовать объекты. Если вы действительно хотите пойти по этому маршруту, проверьте CoreFoundation. (Я не рекомендую идти по этому пути.)

  2. Если у вас есть какой-то сумасшедший фабричный метод, который создает тонн autorelease бассейнов, то я бы, вероятно, сделать что-то вроде этого:

    + (id) crazyFactoryMethodWithFoo:(id)foo { 
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
        id returnValue = nil; 
        //generate gobs of autoreleased objects 
        returnValue = [something retain]; 
        [pool release]; 
        return [returnValue autorelease]; 
    }

    Явно сохраняя возвращаемое значение перед сливом пула, вы гарантируете, что возвращаемое значение будет зависеть от уничтожения пула авторесурсов. Затем вы балансируете это значение retain путем автоматического восстановления возвращаемого значения и возврата его.

+0

@Dave DeLong это было хорошо. Проблема в том, что я все время использую NSUserDefaults ... и методы этого класса создают объекты с автореализацией. Теперь я понимаю, почему Apple не рекомендует. Я также использую методы NSString все время, как и тот, который вы упомянули. И во время цикла я получаю эти странные проблемы. Каково ваше предложение заменить NSUserDefaults в простой форме? Благодарю. – GSchv

+0

@GSchv Почему, по-вашему, вам нужно заменить 'NSUserDefaults'? Если он возвращает вам объект с автореализацией и вы хотите висеть на этом объекте за пределами жизни текущего пула автозапуска, тогда просто «удерживайте» объект (а затем «отпустите» его, когда вы закончите с ним). –

+0

'[pool drain]' является предпочтительным методом http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html # // apple_ref/occ/instm/NSAutoreleasePool/release – cobbal

2

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

for (NSUInteger i = 0; i < 1000000000; i++) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    // do the work 

    [pool release]; 
} 

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

+0

. Благодарю. – GSchv