【问题标题】:should i release strong properties by myself?我应该自己释放强大的属性吗?
【发布时间】:2017-03-31 19:38:43
【问题描述】:

我知道但不完全了解所有弧线是如何工作的。 我知道何时使用弱属性来防止内存泄漏。 但我想了解别的。 如果我有UIViewController 在他内部具有强大的自定义视图,如下所示: @property (nonatomic) UIView myView;(如果我们不指定任何内容,则默认为强)。 如果这个观点是弱的,我知道不需要在意释放它,但是强呢? 在我的 ViewController didDisappear / dealloc 强大后它是否还活着? 1.我应该在viewWillDisappear中将此视图设置为nil吗? 2. 为什么我创建了一个weak property,调用它的init方法后它就不存在了?

【问题讨论】:

    标签: ios objective-c memory-management automatic-ref-counting


    【解决方案1】:

    让我们看看我们是否可以提供帮助:

    如果我有UIViewController,在他里面有这样的强自定义视图:@property (nonatomic) UIView myView;(如果我们没有指定任何东西,默认是强的)。如果这个观点是弱的,我知道不需要在意释放它,但是强呢?在我的 ViewController didDisappear / dealloc 强大后它是否还活着?

    不要考虑引用计数或释放,ARC 真的可以扭转局面。 strongweak等属性与变量相关联,您可以通过以变量为中心的视图来理解这一点,其中变量是参与者——控制被引用对象生命周期的实体。

    当一个引用被存储到一个具有 strong 属性的变量中时采用这种观点,然后该变量会通知 ARC 它需要被引用的对象。

    从变量中删除该引用;例如通过用另一个引用或nil 覆盖它;然后变量告诉 ARC 它不再需要被引用的对象。

    只要至少有一个变量告诉 ARC 该对象是必需的并且尚未撤销该要求,ARC 本身就会简单地保留一个对象。

    您的问题是,当 ARC 删除具有实例变量且具有强属性的对象时会发生什么。从以变量为中心的观点来看,问题变成了:当变量本身被销毁时会发生什么?

    答案是具有strong属性的变量的最后一个动作。并在其中存储了一个引用,就是告诉 ARC 该变量不再需要保留引用的对象。

    1. 我应该在 viewWillDisappear 中将此视图设置为 nil 吗?

    如果变量本身在您需要存储在变量中的引用所引用的对象之后很长时间仍将继续存在,则只需将具有strong属性的变量设置为nil

    例如如果您有一个长期存在的对象,该对象在其生命周期内会在其实例变量之一中短时间存储对大对象的引用,那么在其他时间将该变量设置为 nil 是有意义的。

    1. 为什么当我创建一个弱属性时,我调用它的“init”方法后它就不再存在了?

    我在这里假设您的意思是“创建一个对象并将对它的引用存储在一个弱属性中”。

    在以变量为中心的视图中,具有 weak 属性的变量不会像具有 strong 属性的变量那样告诉 ARC 保留对象,而是监视引用的对象,当它消失时,它会将自己设置为 @ 987654326@.

    如果您创建一个对象,只要在具有 strong 属性的变量中存储对它的引用,ARC 就会保留它。如果您对引用所做的只是将其存储在具有弱属性的变量中,则 ARC 不需要保留对象。


    将变量视为上述参与者当然是一个类比,变量本身不是活动实体。实际上发生的是,在编译期间,编译器会插入执行上述变量操作的指令。结果是一样的。


    TL;DR:strong 和 weak 是与 变量 相关联的属性,而不是与引用相关联的属性。考虑 变量 的生命周期以及其中存储的内容,以确定是否保留或删除任何对象。

    HTH

    【讨论】:

      【解决方案2】:

      强引用(您将在大多数情况下使用)意味着您想“拥有”您使用此属性/变量引用的对象。只要您使用强引用指向它,编译器就会注意您分配给此属性的任何对象都不会被破坏。只有将属性设置为 nil 后,对象才会被销毁(除非一个或多个其他对象也持有对它的强引用)。

      Stackoverflow answer

      所以,是的,如果你不再使用它,你应该将你的 strong 属性设置为 nil。

      【讨论】:

        【解决方案3】:

        Strong 顾名思义,由您的类“强烈”持有,也就是说,只要至少有一个类持有对该对象的引用,该对象就永远不会从内存中释放。如果持有“strong”对象的类被释放,在你的情况下是你的UIViewController,那么对象会自动从内存中删除,你不必将它设置为 nil在dealloc中手动。有一个著名的例子:

        假设有 5 个孩子拿着气球,他们都用力地拿着它。只要一个孩子紧紧抓住它,气球就永远不会飞走。现在,如果有 5 个孩子,只有 一个 紧紧抓住气球,而其他人则松散地抓住它(弱)。抓着气球的孩子一松手,气球就会飞走。 (我可能会解释一下,但我希望你能理解!)

        因此,对于您的第一点,您不必每次都将其设置为 nil,除非情况需要,因为 ARC 这样做。

        【讨论】:

          【解决方案4】:

          ARC 正在计算 strong 对对象的引用。只要此计数为零,就会立即释放内存。您不需要设置对nil 的引用或使用dealloc

          如果您像示例中那样初始化weak 属性,它会立即被释放,因为强引用计数为零。

          weak 用于中断保留周期。一个典型的例子是代表。在以下示例中,ObjectA 对其delegate (ObjectB) 有一个强引用。这是一个保留循环,两个对象都不会被释放:

          @protocol ObjectADelegate <NSObject>
              // requirements
          @end
          
          @interface ObjectA : NSObject
              @property (strong) id<ObjectADelegate> delegate;
          @end
          
          @interface ObjectB : NSObject <ObjectADelegate>
              @property (strong) ObjectA *instanceA;
          
          @end
          
          @implementation ObjectB
          
          - (instancetype)init {
              self = [super init];
              if (self) {
                  self.instanceA = [ObjectA new];
                  self.instanceA.delegate = self;
              }
          
              return self;
          }
          
          @end
          

          要解决此问题并打破保留周期,请将委托属性设置为 weak

          @interface ObjectA : NSObject
              @property (weak) id<ObjectADelegate> delegate;
          @end
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-03-21
            • 2017-04-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-27
            • 2021-08-11
            • 1970-01-01
            相关资源
            最近更新 更多