0

С ARC поддержки (XCode 4.3.2, IOS 4,0), _CFAutoreleasePoolPrintPools() не печатает адрес маркеров в любых бассейнах. Я проверил, что токен выпущен, как ожидается, после окончания пула, поэтому нет проблем, но что-то идет за сценой. Я подозреваю, что это может быть связано с objc_autoreleaseReturnValue.NSMutableString не перечислен в autoreleasepool по _CFAutoreleasePoolPrintPools()

@autoreleasepool { 
    NSMutableString *token = [NSMutableString string]; 
    // When following line uncommented, 
    // **token** is listed in autorelease pool by _CFAutoreleasePoolPrintPools. 
    //[token appendFormat:@"%@", @"xyz"]; 

    NSLog(@"%@", token); 

} 

Итак, не _CFAutoreleasePoolPrintPools() надежный? Как может токен быть автореализованным, хотя не указан в любом пуле авторефератов?

Редактировать: Как я узнал причину и определил, что она уже указана, appendFormat не должен работать иначе. Похоже, что при вызове appendFormat адреса памяти были в диапазоне ([1..F] XXX XXXX), поэтому _CFAutoreleasePoolPrintPools точно перечисляет эти адреса и я могу найти адрес при поиске.

ответ

0

Я был укушен левыми самыми избыточными нулями в адресе памяти. Я непосредственно копировал и искал адрес, возвращенный для токена. Экземпляр NSMutableString фактически отображается как __NSCFString в списке, возвращаемом _CFAutoreleasePoolPrintPools().

(lldb) po token 
(NSMutableString *) $1 = 0x[-->0<--]898e690 

(lldb) po (NSString *)_CFAutoreleasePoolPrintPools() 
...  
objc[731]: [0x82dc1a8] ################ POOL 0x82dc1a8 
objc[731]: [0x82dc1ac]   0x898e690 __NSCFString 
3

Это волшебство objc_retainAutoreleaseReturnValue. Если автореализованный объект будет немедленно сохранен вызывающим абонентом, он не будет автореализован - поэтому он не будет отображаться в пуле автозаполнения. Я поднял окно помощника сборки и посмотрел вызов objc_retainAutoreleaseReturnValue сразу после вызова obj_msgSend для вызова [NSMutableString string].

Для получения дополнительной информации см. this blog post. Он ссылается на комментарии в Apple code, что говорит:

objc_autoreleaseReturnValue() рассматривает инструкции звонящего после возвращения. Если инструкции вызывающего абонента немедленно вызовут objc_autoreleaseReturnValue, тогда вызываемая команда отключает -autorelease и сохраняет результат в локальном хранилище потоков. Если вызывающий абонент не имеет , он выглядит так, как будто он сотрудничает, а звонящий звонит -авторитет как обычный.

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

Отмеченные объекты указателя участвуют в схеме быстрого автообновления , поскольку это сохраняет сообщения отправляет. Они не вводятся в пул автообношений в медленном случае.

+0

Я забыл упомянуть, что retainCount увеличивается на objc_retainAutoreleasedReturnValue() и retainCount 2 после того, как строка создается с помощью метода строки. Я думаю, что [строка NSMutableString] возвращает строку с автореализацией, поэтому objc_retainAutoreleasedReturnValue() сохраняет ее. – lockedscope