Подсчет ссылок или сохранение количества (управление памятью)
Приведенный ниже код работает нормально, вы можете запустить его в своей системе для подтверждения.
Мой вопрос, как вы можете видеть, метод dealloc вызывается только тогда, когда счет сохранения достигает нуля, то есть освобождается память для объекта RetainTracker. Однако проблема заключается в том, что, когда я записываю счет сохранения в методе dealloc, он все равно показывает счет сохранения 1. Почему это происходит?
Вот мой код:
#import <Foundation/Foundation.h>
@interface RetainTracker : NSObject
@end
@implementation RetainTracker
- (id)init {
if (self = [super init]) {
NSLog(@"init: Retain count of %lu",(unsigned long)[self retainCount]);
}
return self;
}
- (void)dealloc {
NSLog(@"Dealloc called bye bye!==>%lu",(unsigned long)self.retainCount);
[super dealloc];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
RetainTracker *myRetainTracker = [RetainTracker new];
[myRetainTracker retain]; // count-->2
NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);
[myRetainTracker release];// count -->1
NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);
[myRetainTracker retain];// count -->2
NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);
[myRetainTracker release];// count -->1
NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);
[myRetainTracker release];// count -->0
NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);
}
return 0;
}
Вот журналы:
init: Retain count of 1
The retain count is ==>2
The retain count is ==>1
The retain count is ==>2
The retain count is ==>1
Dealloc called bye bye!==>1
The retain count is ==>1
2 ответа
Это не удивительно, release
код, вероятно, выглядит так (в псевдокоде):
- (void)release {
if (retainCount > 1) {
retainCount -= 1
} else {
// no need to set the retainCount to 0 here,
// the object now ends its existence
[self dealloc]
}
}
Кроме того, ваш последний NSLog
фактически получает доступ к объекту, который больше не существует, что может привести к сбою.
Обратите внимание, что значение прочитано из retainCount
никогда не следует полагаться. Это просто деталь реализации. Намного безопаснее думать retain
а также release
как передача права собственности.
От retainCount
документация:
Не используйте этот метод.
а также
Этот метод не имеет значения при отладке проблем управления памятью. (...) очень маловероятно, что вы можете получить полезную информацию с помощью этого метода.
Переключите свой проект на ARC. Шутки в сторону. Я забыл все, что я знал о сохранении / освобождении три года назад. Помимо этого, сохранение количества объектов в процессе освобождения не имеет смысла. Бесполезно удивляться этому.