Подтвердить что ты не робот

Количество ссылок в ARC

У меня есть небольшая путаница в ARC ссылке count, можете ли вы рассказать мне, что будет ссылочным счетом следующего кода.

var vc1 = UIViewController()
var vc2 = vc1
var vc3 = vc2
weak var vc4 = vc3

Вопрос: каким будет:

  • счетчик ссылок vc1?
  • количество ссылок vc2?
  • количество ссылок vc3?
  • счетчик ссылок vc4?
4b9b3361

Ответ 1

Здесь vc1, vc2, vc3 относятся к одному и тому же объекту. Итак, подсчет ссылок этого объекта равен 3. Когда vc4 ссылаются на один и тот же объект, так как он является слабым эталоном, счетчик ссылок не будет увеличиваться на 1. Таким образом, счетчик ссылок после этого также будет 3

  • Счетчик ссылок UIViewController, который создается и передается vc1 после первой строки кода: 1.

    var vc1:UIViewController? = UIViewController() // strong reference 
    
  • После vc2 относится к тому же объекту, что и vc1. Счетчик ссылок на объект превращается в 2

    var vc2:UIViewController? = vc1 // strong reference
    
  • После vc3 относится к тому же объекту, что и vc1 и vc2. Счетчик ссылок на объект превращается в 3

    var vc3:UIViewController? = vc2 // strong reference
    
  • После vc4 относится к тому же объекту, что и vc1, vc2 и vc3. Поскольку vc4 является слабым эталоном, счетчик ссылок не будет увеличиваться. Это значит, что счет еще 3.

    weak var vc4:UIViewController? = vc3 // weak reference
    

Что это значит:

Выполните следующий код.

   vc1 = nil; // reference count = 3-1 = 2
   vc2 = nil; // reference count = 2-1 = 1
   vc3 = nil; // reference count = 1-1 = 0 and object is destroyed

Теперь напечатайте значение vc4. Это будет nil. Это происходит потому, что счетчик ссылок объекта обращается в нуль, и все переменные относятся к одному и тому же объекту.

Edit:

Использование CFGetRetainCount в приведенном ниже коде дает следующие результаты, как указано здесь:

var vc1:NSDate? = NSDate()
print(CFGetRetainCount(vc1)) // 2 - I expected this to be 1 as only one variable is strongly referring this object. 

var vc2:NSDate? = vc1
print(CFGetRetainCount(vc1)) // 3 - reference count incremented by 1 (strong reference)

var vc3:NSDate? = vc2
print(CFGetRetainCount(vc3)) // 4 - reference count incremented by 1 (strong reference)

weak var vc4:NSDate? = vc1
print(CFGetRetainCount(vc1)) // 4 - reference count not incremented (weak reference)

vc1 = nil
print(CFGetRetainCount(vc2)) // 3 - reference count decremented by 1 (strong reference removed)

vc2 = nil
print(CFGetRetainCount(vc3)) // 2 - reference count decremented by 1 (strong reference removed)

vc3 = nil 
print(vc4) // nil - reference count should be decremented by 1 (last strong reference removed)

// Also due to the final line vc3 = nil, reference count should become zero
// However, we can't use `CFGetRetainCount` to get reference count in this case
// This is due to the final strong reference being removed and object getting destroyed

Причина, по которой CFRetainCount дает 2 в 1-й строке, обсуждалась здесь . Спасибо @CodaFi и @Sahil за ваше обсуждение в комментариях

Ответ 2

Вы можете использовать CFGetRetainCount функцию для проверки количества ссылок.

var vc1 = UIViewController()
var vc2 = vc1
var vc3 = vc2
weak var vc4 = vc3


print(CFGetRetainCount(vc1)) //4
print(CFGetRetainCount(vc2)) //4 
print(CFGetRetainCount(vc3)) //4
print(CFGetRetainCount(vc4)) //4

вы также можете ссылаться на этот Получить Ref Count

Ответ 3

По-моему, vc1-vc3 увеличивает количество удержаний, а свойство по умолчанию - strong, пока мы не укажем их как weak.

strong: Сильный, как правило, используется классом для установления права собственности на объект. Он увеличивает количество удержаний (что-то ARC имеет для вас), он в основном сохраняет объект, на который указывает в памяти, пока этот экземпляр класса не перестанет указывать на него. Обычно это то, что вы хотите, но там оно может вызвать нечто, называемое "циклом сохранения".

В случае vc4, как вы dec как weak:

слабый:. Это дает указатель на объект, но не требует права собственности и не увеличивает счетчик сохранения. Он в основном сохраняет действительный указатель на объект, если другой класс указывает на него сильно. Если ничего не пытается сохранить, слабый указатель автоматически устанавливается на nil.

Ответ 4

1,2,3,4 - счетчик ссылок будет 3

Единственное исключение, когда счетчик ссылок не будет увеличиваться - 4-я строка из-за слабого модификатора