如果我们声明所有属性均为弱,将会发生什么?

时间:2019-01-16 13:36:36

标签: objective-c automatic-ref-counting

例如,有一个课程

@interface Person: NSObject {
    @property (weak) NSString *str;
@end

@implementation
    - (void) init {
      str = @"XYZ";
    }
@end
  • 将所有属性声明为弱是安全的,以避免引用计数 高架?
  • 如果不安全,那为什么不安全?
  • str的引用计数是多少?

2 个答案:

答案 0 :(得分:2)

  

将所有属性声明为弱是否安全以避免引用计数开销?

这有两个问题。首先,weak不能避免引用计数。实际上,它执行的簿记操作比strong还多。参见Lots of overhead for weak property?可以很好地讨论这一点。

接下来,这是错误的,因为weakstrong表示无法互换的不同事物。正如MartinM所指出的,如果您设置了属性weak,那么只要没有其他限制,它们就会在您分配它们后立即消失。

  

如果不安全,那为什么不安全?

这是完全安全的。只是行不通。您的程序将具有明确定义的行为,并且不会因标记所有属性weak而崩溃。您的大多数财产将仅为nil。如果您使用unsafe_unretained而不是weak,则可以避免一些引用计数开销,并且您的程序通常会崩溃(因为对象仍然被破坏,指针将变得无效)。

  

str的引用计数是多少?

即使感觉像一个问题,这也不是一个有意义的问题。在此特定情况下,答案为9,223,372,036,854,775,807,因为这总是静态字符串的保留计数,因为静态字符串无法销毁并忽略保留/释放调用。 (在ObjC中,该值为NSNotFound。我相信以前该值返回1,152,921,504,606,846,975,但我的测试表明它已更改。)

但是在一般情况下,在此时此刻可以是任何事情。而且,此时与事件循环结束时(自动释放池耗尽时)的情况可能会大不相同。不要追逐保留计数值。他们将永远骗你。为您关心的事物创建强大的参考。仅在出于特殊目的需要它们时才创建弱引用。

保留计数是内部实现的详细信息。在ARC之前,它们是misleading to the point of uselessness。从ARC开始,他们就像在问“汇编指令将编译成什么样的指令”。这很重要,但这取决于程序的其他所有内容以及其编译方式。

如果您有与内存管理相关的特定性能问题,则可以根据具体情况采用相应的技术来解决,StackOverflow可以为您提供帮助。但是ARC非常擅长优化内存管理。让它做好自己的工作。

答案 1 :(得分:1)

您应该知道哪些属性应该弱而哪些属性应该强。通常,通常将所有IBOutlet声明为弱函数,因为它们被情节提要中的视图保留,因此不必在视图控制器中保留强引用。

另一个例子是应该总是弱的委托,否则它将阻止委托(主要是另一个视图控制器)被释放,因为委托的持有人还活着。

在您的情况下,str在初始化后将为nil,因为没有其他对其内容的引用。如果这样做,实际上应该收到编译器警告。

通过更详细的说明来查看此线程:Weak and strong property setter attributes in Objective-C