Выпуск Objective C, авто-выпуск и типы данных

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
25
задан Michael 2 August 2009 в 19:11
поделиться

2 ответа

Как отмечено в правилах управления памятью , всякий раз, когда у вас есть объект, который вы создали с помощью +alloc, +new, -copy или -mutableCopy, вы владеете им и несете ответственность за него. для выпуска его в какой-то момент. (На самом деле, +new - это просто сокращение для [[MyClass alloc] init].) Как вы заметили, создание массива через [NSArray new] без его освобождения - утечка памяти). Однако, если вы правильно обрабатываете этот объект, в какой-то момент его можно отпустить. Например:

  • Если метод, который использует , массив вызывается из в метод, который создает массив, то вы должны иметь возможность освободить массив после того, как он был использован. Если внутреннему методу необходимо сохранить более постоянную ссылку на массив, то этот метод отвечает за отправку -retain и, в конечном итоге, -release объекту. Например:

    - (void)myMethod {
        NSArray *removals = [NSArray new];
        // ...
        [someObject someOtherMethod:removals];
        [removals release];
    }
    
  • Если вы создали массив в методе -init для объекта, то метод -dealloc ] может освободить его, когда объект уничтожен.

  • Если вам нужно создать массив, а затем вернуть его из метода, вы обнаружили причину, по которой было изобретено автоматическое освобождение. Вызывающий ваш метод не несет ответственности за освобождение объекта, так как это не метод +alloc, +new, -copy или -mutableCopy, но вы должны убедиться, что он в конце концов освобожден. В этом случае вы вручную вызываете -autorelease для объекта, прежде чем вернуть его. Например:

    - (NSArray *)myMethod {
        NSArray *removals = [NSArray new];
        // ...
        return [removals autorelease];
    }
    

Когда вы создаете массив с помощью +arrayWithCapacity:, вы не вызываете один из «специальных» методов, поэтому вам не нужно освобождать результат , Это, вероятно, реализовано в -autorelease, очень похоже на последний пример выше, но не обязательно. (Между прочим, вы также можете создать пустой автоматически выпущенный NSMutableArray с помощью [NSMutableArray array]; метод находится в NSArray, поэтому он не будет отображаться в документации по NSMutableArray, но он создаст изменяемый массив при отправке в класс NSMutableArray. ) Если вы собираетесь возвращать массив из вашего метода, вы можете использовать его как сокращение для [[[NSMutableArray alloc] init] autorelease], но это всего лишь ярлык. Однако во многих ситуациях вы можете создать объект с помощью -init или +new и вручную отпустить его в соответствующее время.

65
ответ дан John Calsbeek 2 August 2009 в 19:11
поделиться

Какао использует определенные соглашения об именах. Все, что начинается с alloc, new или copy, возвращает что-то с keepCount, равным 1, и вы должны освободить. Все остальное, что возвращает функция, имеет сбалансированное значение keepCount (оно может удерживаться чем-то другим или может быть сохранено и освобождено).

Итак:

NSMutableArray *removals = [NSMutableArray new];

Имеет значение keepCount, равное 1, и:

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];

или

NSMutableArray *removals = [NSMutableArray array];

Не делайте этого, поскольку методы не имеют префиксов alloc, new или copy. Все это описано в документации по управлению памятью . В частности:

Вы становитесь владельцем объекта, если вы создайте его, используя метод, имя которого начинается с «alloc» или «new» или содержит «копию» (например, alloc, newObject или mutableCopy), или если вы отправьте ему сообщение о сохранении. Ты несет ответственность за отказ владение объектами, которыми вы владеете, используя релиз или автозапуск. В любое другое время вы получаете объект, вы не должны отпустите.

4
ответ дан 28 November 2019 в 18:00
поделиться