ARC 中的引用计数
Reference count in ARC
我对ARC
引用计数有点困惑你能告诉我波纹管代码的引用计数是多少吗?
var vc1 = UIViewController()
var vc2 = vc1
var vc3 = vc2
weak var vc4 = vc3
问题会是什么:
- vc1 的引用计数?
- vc2 的引用计数?
- vc3 的引用计数?
- vc4 的引用计数?
这里,vc1
、vc2
、vc3
指的是同一个对象。所以,那个对象的引用计数是3。当vc4
引用同一个对象时,由于是弱引用,引用计数不会加1。所以,这之后的引用计数也会是3
第一行代码后vc1
创建并引用的UIViewController
对象的引用计数为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
。发生这种情况是因为对象的引用计数变为零并且所有变量都引用同一个对象。
编辑:
在下面的代码中使用 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 的原因已经讨论过 here。感谢@CodaFi 和@Sahil 在评论中的讨论
1,2,3,4 - 引用计数将为 3
引用计数不会递增的唯一例外 - 第 4 行,因为修饰符较弱
在我看来,vc1 到 vc3 增加了保留计数,默认 属性 是 strong
,直到我们将它们指定为 weak
.
strong: Strong 通常由 class 用来建立对象的所有权。它增加了保留计数(ARC 为您处理的事情),它基本上将指向的对象保留在内存中,直到 class 实例停止指向它。这通常是您想要的,但它可能会导致所谓的“保留循环”。
在 vc4 的情况下,您 dec 为 weak
:
weak: 这给出了一个指向对象的指针,但不声明所有权,也不增加保留计数。只要另一个 class 强烈指向它,它基本上就会保留一个指向对象的有效指针。如果没有其他东西试图保留它,弱指针会自动设置为 nil。
您可以使用 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
你也可以参考这个Get Ref Count
我对ARC
引用计数有点困惑你能告诉我波纹管代码的引用计数是多少吗?
var vc1 = UIViewController()
var vc2 = vc1
var vc3 = vc2
weak var vc4 = vc3
问题会是什么:
- vc1 的引用计数?
- vc2 的引用计数?
- vc3 的引用计数?
- vc4 的引用计数?
这里,vc1
、vc2
、vc3
指的是同一个对象。所以,那个对象的引用计数是3。当vc4
引用同一个对象时,由于是弱引用,引用计数不会加1。所以,这之后的引用计数也会是3
第一行代码后
vc1
创建并引用的UIViewController
对象的引用计数为1.var vc1:UIViewController? = UIViewController() // strong reference
后
vc2
与vc1
指代同一个对象。对象的引用计数变为2var vc2:UIViewController? = vc1 // strong reference
后
vc3
与vc1
、vc2
指代同一个对象。对象的引用计数变为3var 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
。发生这种情况是因为对象的引用计数变为零并且所有变量都引用同一个对象。
编辑:
在下面的代码中使用 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 的原因已经讨论过 here。感谢@CodaFi 和@Sahil 在评论中的讨论
1,2,3,4 - 引用计数将为 3
引用计数不会递增的唯一例外 - 第 4 行,因为修饰符较弱
在我看来,vc1 到 vc3 增加了保留计数,默认 属性 是 strong
,直到我们将它们指定为 weak
.
strong: Strong 通常由 class 用来建立对象的所有权。它增加了保留计数(ARC 为您处理的事情),它基本上将指向的对象保留在内存中,直到 class 实例停止指向它。这通常是您想要的,但它可能会导致所谓的“保留循环”。
在 vc4 的情况下,您 dec 为 weak
:
weak: 这给出了一个指向对象的指针,但不声明所有权,也不增加保留计数。只要另一个 class 强烈指向它,它基本上就会保留一个指向对象的有效指针。如果没有其他东西试图保留它,弱指针会自动设置为 nil。
您可以使用 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
你也可以参考这个Get Ref Count