О 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]);

Когда я пытаюсь понять авторелиз и релиз, я в замешательстве. если использовать [string autorelease], то после отправки сообщения release в пул значение retainCount строки по-прежнему равно 1. Но используйте [string release] для замены [string autorelease], в конечном итоге retainCount строки будет равен 0. Что я знаю об авторелизе, так это "добавьте объект в текущий пул авторелиза для последующего выпуска, отправив ему сообщение авторелиза". Почему я послал ему авторелизное сообщение и освободите бассейн, я все еще могу получить доступ к объекту.

2 2

2 ответа:

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

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

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

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

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

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