Когда выпускается объект autorelease?

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

__weak id ref;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *str = [NSString stringWithFormat:@"test"]; // add autoreleasePool
    ref = str;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear:%@",ref); // result test
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"viewDidAppear:%@",ref); // result test
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@",ref); // If I click long after,But it has not been released
}

person Corbin    schedule 29.07.2018    source источник


Ответы (1)


[NSString stringWithFormat:] не обещает вам объект в пуле авторелиза. Он обещает вам объект, который вам не нужно выпускать. В этом случае он возвращает вам постоянную строку, а постоянная строка никогда не уничтожается. Также можно бесплатно вернуть вам кэшированное значение или значение, совместно используемое с другими читателями, помеченный указатель или одиночный элемент. NSNumber имеет множество подобных оптимизаций.

На основной вопрос: когда локальный пул автоматического освобождения будет слит, один release будет отправлен объекту для каждого autorelease, который ранее был отправлен объекту в этом пуле. Уничтожит ли это объект или нет, зависит от того, какие другие удержания были наложены на него.

Я бы ожидал, что подобное значение будет вести себя ближе к тому, что вы ожидаете, но обещаний нет:

[NSString stringWithFormat:@"something a little long and computed: %d", rand()]
person Rob Napier    schedule 29.07.2018
comment
Также обратите внимание, что в ARC семантика сохранения/освобождения/автоматического освобождения может измениться по прихоти компилятора. Вполне вероятно, что вы увидите больше трафика авторелиза, например, в сборках отладки по сравнению с сборками выпуска. - person bbum; 29.07.2018
comment
В MRC, когда высвобождается объект автовыпуска? Я знаю, что объект автовыпуска в итерации цикла выполнения заканчивается. И мне было интересно, что если я вызываю объект автовыпуска через 10 минут, я думаю, что цикл выполнения повторялся много раз. Итак, объект автовыпуска был выпущен. Но я попробовал его и обнаружил, что результат был не таким, как я ожидал. - person Corbin; 30.07.2018
comment
В случае с MRC, как я уже говорил выше, когда локальный пул автовыпуска опустошается, объекту будет отправлен один релиз для каждого авторелиза, который ранее был отправлен объекту в этом пуле. И да, есть пул автовыпуска, который сливается в конце каждого цикла выполнения. Но все, что я здесь сказал, относится к MRC (это относится к MRC больше, чем к ARC). Нет никаких обещаний, что возвращаемое значение stringWithFormat: является автоматически выпущенным объектом. Есть только обещание, что вам не нужно его выпускать. - person Rob Napier; 30.07.2018
comment
Кроме того, даже объект с автоматическим освобождением не может быть уничтожен при опорожнении пула. На него обещают отправить release. Это может не разрушить объект. - person Rob Napier; 30.07.2018
comment
Большое спасибо! Я думаю, что понял. - person Corbin; 01.08.2018