【问题标题】:Why weak IBOutlet NSLayoutConstraint turns to nil when I make it inactive?为什么当我使其处于非活动状态时,弱 IBOutlet NSLayoutConstraint 变为 nil?
【发布时间】:2016-10-29 08:16:31
【问题描述】:

我的应用中有一个IBOutlet NSLayoutConstraint。很简单:

@property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;

在某些时候我想停用此约束:

self.leftConstraint.active = NO;

它发生在从cellForRowAtIndexPath: 调用的方法中。并且在上面的行之后约束变为 nil 。但是,如果我将此属性声明为strong,那么没关系,它不会变成零。谁能解释一下为什么会这样?

【问题讨论】:

    标签: ios objective-c uikit iboutlet ios-autolayout


    【解决方案1】:

    当您的出口是weak 时,唯一的strong 引用来自视图的constraints 属性。停用约束会将其从该数组中删除,因此不再有强引用。

    【讨论】:

    • 小学,Watson))) 非常感谢!
    • 我得出了同样的结论,但是让它变强安全吗?我的约束是在集合视图单元格中,我担心在回收单元格时持有强引用会创建一个保留周期。
    • @Echelon,如果不进一步了解您的班级关系,就无法回答这个问题。但是,只要有明确的中断点,循环就可以了。
    • 一种解决方案可能是更改约束的constant 值。
    • @Echelon 我相信,是的,创建NSAutolayoutConstraint strong 是安全的。据我了解,NSAutolayoutConstraint 本身有 weak 对其约束的元素的引用,因此不存在循环的可能性。不过,我很高兴得到纠正!这似乎是一个可以通过相当简单的单元测试来解决的问题。创建两个视图。对它们施加强烈的约束。发布您对视图的强引用。检查视图上的弱引用是否仍然到达它们。如果是,则约束持有它们,否则,它不是。
    【解决方案2】:

    一种可能的解决方法是更改​​约束优先级而不是使其处于非活动状态:

    @property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;
    (...)
    self.leftConstraint.priority = 250;
    

    那么,self.leftConstraint 不会被释放。

    编辑:

    Xcode 不支持更改所需 (=1000) 约束的优先级,因此请确保在 1...999 之间切换。

    【讨论】:

      【解决方案3】:

      首先将 IBOutlet 变量更改为可选项。即:

      来自:

      @IBOutlet weak var myConstraint : NSLayoutConstraint!
      

      到:

      @IBOutlet weak var myConstraint : NSLayoutConstraint?
      

      现在,为了将来更容易管理/更改情节提要,添加一个新变量(例如 myConstraint_DefualtValue)并将其设置为 myConstraint 的值在 viewDidLoad

      var myConstraint_DefualtValue = CGFloat(0)
      override func viewDidLoad() {
          super.viewDidLoad()
      
          self.myConstraint_DefualtValue = self.myConstraint.constant
      
      }
      

      我认为为什么需要在 viewDidLoad 而不是其他地方设置它是显而易见的

      那么当你想停用它时:

      self.myConstraint?.isActive = false
      

      当您想重新激活它时(假设您将视图作为插座(myViewThatHasTheConstraint)并且约束是 height 约束):

      self.myConstraint = self.myViewThatHasTheConstraint.heightAnchor.constraint(equalToConstant: self.myConstraint_DefualtValue);
      self.myConstraint?.isActive = true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多