Вы можете использовать CFGetRetainCount
с объектами Objective-C, даже под ARC:
NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));
Это , а не , особенно полезно для отладки, однако, по причинам, подробно описанным в другом месте . Если вам необходимо понять, где объект удерживается и освобождается, ознакомьтесь с этим ответом , чтобы получить помощь по использованию инструмента Allocations.
Единственный случай, когда я обнаружил, что проверка количества записей действительно полезна, - это метод dealloc
, когда что-то сохраняет и автоматически освобождает объект, который был освобожден. Это приведет к сбою позже, когда пул автообновления будет слит. Вы можете точно определить причину этого, проверив счетчик до и после каждого сообщения. Таким образом, я обнаружил, что метод observationInfo
(который сам обычно полезен только для отладки) сохраняет и автоматически выпускает self
. Тем не менее, даже такого рода проблемы обычно можно решить, не проверяя счет сохранения, просто обернув все тело dealloc
в блок @autoreleasepool
.
Однако счет сохранения может быть использован для изучения реализации некоторых классов. (Делайте это только для развлечения или любопытства! Никогда не полагайтесь на недокументированные детали реализации в рабочем коде!)
Например, попробуйте это сразу внутри @autoreleasepool
в main
:
NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test
Так что NSNumber
, вероятно, кэширует (или, по крайней мере, повторно) некоторые экземпляры. Но не другие:
n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance. There could be weak
// or unretained references to it, but no other strong references.
NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again. New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.
Вы даже можете обнаружить, что NSNumber
возвращает синглтон, если вы alloc
, но не инициализируете:
n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.
(Обратите внимание, что вы также можете узнать много подробностей о NSNumber
, взглянув на исходный код Core Foundation, который доступен по адресу http://opensource.apple.com. Но кто знает, что вы можете найти, если вы посмотрите на счет сохранения объекты, которые не соединяются бесплатно с объектами в Core Foundation?)