Понимание глубины удержания

280
31

Допустим, у нас есть три объекта: бабушка, родитель и ребенок. Бабушка и дедушка сохраняют родителя, родитель сохраняет ребенка, а ребенок сохраняет родителя. Бабушка и дедушка выпускают родителя.


Что произойдет в этом случае?

спросил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
1
Решение
322

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

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

ответил(а) 2020-04-03T23:56:48.540823+03:00 5 месяцев, 4 недели назад
195

Сохранение цикла - это условие. Когда 2 объекта сохраняют ссылку друг на друга и сохраняются, он создает цикл сохранения, поскольку оба объекта пытаются сохранить друг друга, что делает невозможным его освобождение.


Здесь "Дедушка" сохраняет "родителя", а "родитель" сохраняет "ребенка", где "ребенок" сохраняет "родителя". Здесь устанавливается цикл сохранения между родителем и ребенком. После освобождения бабушки и дедушки родитель и ребенок становятся сиротами, но удержание счета родителя не будет равным нулю, поскольку оно сохраняется у ребенка и, следовательно, вызывает проблему с управлением памятью.


Существует два возможных решения:

1) Используйте слабый указатель на родительский, то есть ребенок должен использовать слабую ссылку на родителя, которая не сохраняется.


2) Используйте методы "закрыть", чтобы разбить циклы удержания.


http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
122

В простом случае рассмотрим два объекта A и B, где A создает и сохраняет B. Когда A создается, он создает B. Когда тот, кто создал A, наконец-то выпускает его, счетчик удержания падает до нуля и освобождается. Если метод dealloc вызывает освобождение на B, показатель сохранения B также падает до нуля, и он также освобождается. [Это предполагает, что никто не сохранил A или B, потому что я делаю все просто.]


Но что произойдет, если B нуждается в ссылке обратно в A, и он сохранит A? Тот, кто создал A, может освободить его. Но так как B также сохранил A, показатель удержания не будет равен нулю. Точно так же, поскольку A сохраняет B, B сохраняет отсчет также не будет идти к нулю. Ни один из них не будет освобожден. Даже если B вызывает метод release в своем собственном dealloc, это не имеет значения, потому что этот метод никогда не будет вызван.


В этот момент у вас есть утечка памяти, потому что у вас нет ссылки на A или B, хотя они оба все еще существуют. Если A или B делает что-то более интенсивным, то вы также можете протекать процессорное время на нежелательные объекты.


В вашем случае A является родителем, а B является дочерним, а любой, кто создал A, является дедушкой.

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
98

Цикл удержания - это цикл, который происходит, когда объект А сохраняет объект B, а объект B сохраняет объект A. В этой ситуации, если один из объектов освобожден:


    Объект A не будет освобожден, поскольку объект B содержит ссылку на
    it (сохранить count > 0).
    Объект B никогда не будет освобожден, если объект А имеет
    ссылку на него (сохранить count > 0).
    Но объект A никогда не будет освобожден, поскольку объект B содержит
    ссылку на него (сохранить count > 0).
    до бесконечности

Таким образом, эти два объекта будут просто зависеть в памяти для жизни программы, даже если они должны, если все будет работать должным образом, освободиться.

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
88

Когда grandparent освобождает родителя, родитель все еще жив, так как ребенок сохраняет родителя.

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
58

Сохраняемый цикл - это условие, когда объекты 2 сохраняют ссылку друг на друга и сохраняются, создают цикл сохранения, поскольку оба объекта старайтесь удерживать друг друга, делая невозможным освобождение.


Пример: Человек живет в отделе, отдел имеет одного человека.


@class Department;

@interface Person:NSObject
@property (strong,nonatomic)Department * department;
@end

@implementation Person
-(void)dealloc{
NSLog(@"dealloc person");
}

@end
@interface Department: NSObject
@property (strong,nonatomic)Person * person;
@end

@implementation Department
-(void)dealloc{
NSLog(@"dealloc Department");
}
@end


Затем назовите его следующим образом:


- (void)viewDidLoad {
[super viewDidLoad];
Person * person = [[Person alloc] init];
Department * department = [[Department alloc] init];
person.department = department;
department.person = person;
}

Вы не увидите журнал dealloc, это круг сохранения.

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
41

Дедушка: Джон Родитель: Тед Ребенок: Мэри

Вот мой пример использования телефонного звонка для иллюстрации:

    Джон звонит Теду и хочет сделать телефонную конференцию с Мэри.

    Тед говорит Джону: "Повесьте трубку, и я позвоню Мэри"

    Тед оставляет Джона в ожидании и звонит Мэри, которая быстро отвечает на звонок.

    Мэри говорит Теду: "Слей мой звонок с Джоном, и я не буду вешать трубку, пока я не закончу"

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

    Джон идет, чтобы объединить звонки с Тедом и Мэри, а затем внезапно умирает.

    Мэри застряла на линии с Джоном, но никогда не повесит трубку, потому что Джон не вернется!

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
41

Поскольку у объекта P сохраняется значение 1, когда оно отпущено, его keepCount переходит в 0, и его метод dealloc вызывается; Это, в свою очередь, вызывает освобождение на объекте C, счетчик которого также переходит в 0; и его метод dealloc вызывается.


Оба объекта P и C освободятся.


Когда вызывается метод dealloc объекта C, в свою очередь вызывается публикация объекта объекта GP, но поскольку GP имеет значение удержания 2, счет сохранения уменьшается до 1, и он продолжает зависать.

ответил(а) 2020-04-03T23:46:03+03:00 5 месяцев, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема