Одна проблема, с которой вы столкнулись, заключается в том, что str никогда не инициализируется, что означает, что str может указывать на ноль (но это не гарантируется). Это определенно указывает на мусор.
Если вы пройдете по своему коду, я почти гарантирую, что ваш выпуск вызывается по nil, что в Objective-C полностью допустимо.
Попробуйте сделать это:
NSString *str = [[NSString alloc] initWithString:@"a string"];
[str release];
[str release];
Вызов release не освобождает объект, он просто уменьшает счет сохранения на 1. Когда счет сохранения объектов равен 0,
[self dealloc];
вызывается автоматически.
Если приведенный выше код не генерирует исключение немедленно, это может быть связано с тем, что фактическое сообщение об освобождении откладывается в какой-то момент в будущем (я не уверен точно, когда dealloc вызывается после того, как число сохранений достигает 0. I думаю, что он вызывается немедленно и в том же потоке, но какой-нибудь другой ниндзя Какао точно об этом узнает).
Что вы можете сделать, это добавить категорию в NSObject, внедрить методы dealloc и release и попытаться обнаружить, что вы там исключение.
- (void)dealloc{
@try
{
[super dealloc];
}
@catch(NSException* ex)
{
NSLog(@"Bug captured");
}
}
- (void)release{
@try
{
[super release];
}
@catch(NSException* ex)
{
NSLog(@"Bug captured");
}
}
Дополнительным бонусом является то, что этот код будет действителен для каждого объекта в вашем приложении, поскольку это категория в NSObject.
Если быть полным, если вы просто будете практиковать их правила управления памятью, у вас все будет хорошо.