2012-04-02 2 views
2

Это мой код:О autorelease/выпуска и [выпуска пула]

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSString *string = [[NSString alloc] initWithFormat:@"s"]; 

[string autorelease]; 
NSLog(@"retainCount of string is %d", [string retainCount]); 

[pool release]; 
NSLog(@"retainCount of string is %d", [string retainCount]); 

Когда я пытаюсь понять autorelease и отпустить, я запутался. Если вы используете [строка autorelease], после отправки сообщения о выпуске в пул, keepCount строки все равно 1. Но используйте [строковый выпуск], чтобы заменить [string autorelease], наконец, сохранитьCount строки будет 0. То, что я знаю об autorelease «добавляет объект в текущий пул автозапуска для последующего выпуска, отправив ему сообщение автореферата». Почему я отправил сообщение об автоопределении и освободил пул, я все равно могу получить доступ к объекту.

+1

keepCount никогда не может вернуть нуль. Обмен сообщениями с деалоцированным объектом приводит к неопределенному поведению. – bbum

ответ

3

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

После того, как вы выделите строку, вы ее обладаете. Когда вы автоматически отправляете строку, вы больше не владеете ею, и она может исчезнуть, когда вы сливаете/освобождаете пул авторесурсов. Если никто не владеет им, то будет исчезнуть, когда вы освободите пул авторефератов. Anywway, вы не можете законно отправлять строковые сообщения после того, как вы выпустили пул авторесурсов.

В текущей реализации строка создается с сохранением числа 1. Автореферат не изменяет счет сохранения. Когда пул освобожден, release отправляется всем объектам в нем, включая вашу строку. Код в релизе выглядит примерно так:

if (retainCount == 1) 
{ 
    [self dealloc]; 
} 
else 
{ 
    retainCount--; 
} 

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

+0

Спасибо U! Это поможет мне понять управление памятью Objective-C. – tzzzoz

-1

Вы должны использовать [пул дренажа] вместо сообщения о выпуске, чтобы освободить все автореализованные объекты в пуле. Это сообщение вызовет [пул релиз] для вас.

+0

'drain' является синонимом' release' в ссылочном подсчитанном коде. – JeremyP

+0

Я пробовал этот метод. Но keepCount строки все еще печатается на консоли. – tzzzoz

+0

Из ссылки 'NSAutoreleasePool':« Когда пул авторасчетов освобожден, он отправляет сообщение о выпуске всем своим автореализованным объектам » – trojanfoe