Objective-C - autoreleasepool (ARC - Автоматический подсчет ссылок) - PullRequest
1 голос
/ 03 декабря 2011

У меня есть сомнения по поводу автоматического повторного пула при автоматическом подсчете ссылок (ARC)

В моем примере (вставлено ниже) у меня есть автозапуск, и у меня нет операторов в блоке автозапуска. После блока автозапуска существует автоматически освобожденный экземпляр (a3).

Ожидаемое поведение:

Я ожидал, что следующее утверждение вызовет утечку памяти, поскольку оно не инкапсулировано в автозапуск.

A* a3 = b1.xa1;

Фактическое поведение:

Фактическое поведение - ошибка утечки памяти во время выполнения

Примечание:

Если автозапуск перемещается после инициализации a3, то во время выполнения выдается ошибка утечки памяти

Мое понимание:

Только операторы в autoreleasepool будут иметь эффект пула autorelease, но в моем примере это не так.

Вопрос:

  1. Какова причина, почему это происходит?
  2. Есть ли какое-либо значение операторы с блоком авто-релиза? или это просто хорошо достаточно иметь пустой блок автозапуска перед авто-выпущенный экземпляр? Если так, почему?

Краткое изложение моего вопроса

Вопрос в том, что вложенные операторы в autoreleasepool имеют такой же эффект, как и операторы размещения после autoreleasepool, даже если он находится вне autoreleasepool

Код:

#import<Foundation/Foundation.h>

@interface A : NSObject
- (void) dealloc;
@end

@implementation A
- (void) dealloc { printf("instance of A deallocated = %p\n", self); };
@end

@interface B : NSObject
@property (weak) A* xa1;
- (void) dealloc;
@end

@implementation B
@synthesize xa1;
- (void) dealloc { printf("instance of B deallocated = %p\n", self); };
@end

int main()
{
    system("clear");

    B* b1 = [[B alloc] init];
    A* a1 = [[A alloc] init];
    A* a2 = [[A alloc] init];

    b1.xa1 = a1; 

    @autoreleasepool
    {}  

    A* a3 = b1.xa1;                     //I expected this to throw a memory leak error, but it doesn't
                                        //Note - b1.xa1 returns an autoreleased instance

    printf("--- end of main\n");

    return(0);
}

1 Ответ

2 голосов
/ 03 декабря 2011
  1. По какой причине это происходит?

Хотя я считаю, что технически линия A* a3 = b1.xa1; "неправильная", ARC достаточно умен, чтобы правильно располагатьвозвращенного объекта без фактического использования пула автоматического выпуска.Это оптимизация производительности ARC (использование пула автоматического выпуска не является бесплатным).По сути, ARC вводит [a1 release] От Apple Переход к примечаниям к выпуску ARC

Компилятор эффективно устраняет многие посторонние вызовы сохранения / освобождения, и много усилий было вложено в ускорениеВремя выполнения Objective-C в целом.В частности, общий шаблон «вернуть сохраняемый / автоматически освобожденный объект» гораздо быстрее и фактически не помещает объект в пул автоматического освобождения, когда вызывающим методом является код ARC.


  1. Имеет ли какое-либо значение включение операторов с авто-выпуском?или достаточно просто иметь пустой блок autoreleasepool перед экземпляром autoreleased?Если так, то почему?

Да.Хотя этот конкретный случай указывает на иное, в общем случае пулы авто-релиза имеют смысл.Все в этом документе об пулах автоматического освобождения все еще действует: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

...