Длина NSString и retainCount.Требуется уточнение - PullRequest
4 голосов
/ 18 июля 2011

Исходя из следующего кода, пожалуйста, сообщите

NSString *str= [[NSString alloc] initWithString:@"Hello world"];   

NSLog(@"Length: %lu\n", [str length]);              // 11
NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975

[str release];

NSLog(@"%lu\n", [str length]);                      // 11
NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975
  1. Первоначально я задавался вопросом, почему число было таким большим, но потом увидел сообщение , объясняющее его .Позвольте мне спросить это вместо этого ... Почему этот номер сильно меняется, если я использую %d против %lu.Первоначально я использовал %d, но получил предупреждение о том, что " Преобразование задано типом int, но аргумент имеет тип NSUInteger (он же unsigned long). Исправлено было изменить %d на %lu"

  2. Почему не уменьшается счет?Большое число по-прежнему отображается без изменений после отправки str release

  3. Почему я все еще могу получить доступ к str после того, как оно было отправлено release?

Ответы [ 2 ]

8 голосов
/ 18 июля 2011

Это может быть трудный ответ, но вы должны это сделать:

  1. Не беспокойтесь об этом. (в терминах% d /% luэти спецификаторы просто ожидают разные типы данных, и% d (int) имеет гораздо меньший и отличный диапазон от% lu (unsigned long))
  2. Не беспокойтесь об этом.
  3. Не делайте этого и особенно не полагайтесь на него.

Возможно, вы начали с постоянной строки (@"Hello world")что память не освобождается при вызове release, а retainCount велик.Но если вам нужно заботиться о retainCount, вы делаете это неправильно.

Вы освобождаете строку в нужном месте, и вот что важно - никогда не пытайтесьиспользуйте его позже.

0 голосов
/ 18 июля 2011

в конечном счете, поведение определяется реализацией NSString - просто используйте retain / release правильно в каждом случае, и вы будете в безопасности.

что, вероятно, происходит: литералы NSString бессмертны.вы можете написать while (1) { [@"String" release]; } и проблем не будет.

вызванный вами копирующий ctor, вероятно, вернет указатель на строковый литерал.в псевдокоде:

- (id)initWithString:(NSString *)str
{
    self = [super init];
    if (self != nil) {
        if ([str _isStringLiteral] || [str _isImmutable]) {
            [self release];
            return [str retain];
        }
        ...
}

, в этом случае вам возвращается указатель на строковый литерал при пропуске через [[NSString alloc] initWithString:stringLiteral].поскольку отправка release в бессмертный строковый литерал ничего не делает, вы можете понять, почему он по-прежнему является допустимым объектом после того, что, как вы можете предполагать, является освобожденным объектом.

никогда не полагается на такие детали / оптимизации, просто используйте обычныйвремя жизни и подсчет ссылок, и все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...