О 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 ответа:
Вот в чем дело:
retainCount
- это деталь реализации. Вы никогда не можете полагаться на то, что это какая-то конкретная ценность. Все, о чем вам действительно нужно думать, это о том, являетесь ли вы владельцем объекта или нет.После выделения строки она становится вашей собственностью. Когда вы авторелизируете строку, вы больше не владеете ею, и она может исчезнуть, когда вы сливаете / освобождаете пул авторелиза. Если он никому больше не принадлежит, онисчезнет, когда вы освободите пул авторелиза. В любом случае, вы не можете законно отправить строковые сообщения после освобождения пула авторелиза.
В текущей реализации строка создается с числом сохранения 1. Авторелиз не изменяет счет удержания. Когда пул освобождается,
release
отправляется всем объектам в нем, включая вашу строку. Код в релизе выглядит примерно так:if (retainCount == 1) { [self dealloc]; } else { retainCount--; }
Таким образом, вы можете видеть, что число удержаний никогда не опустится до нуля. Ваш окончательный NSLog работает, потому что память, используемая строкой еще не переработан.