经常在Swift使用Snapkit或者Objective-C中Masonary框做约束
let testView = UIView()
testView.backgroundColor = UIColor.cyan
view.addSubview(testView)
testView.snp.makeConstraints { (make) in
make.width.equalTo(100) // 宽为100
make.height.equalTo(100) // 高为100
make.center.equalTo(view) // 位于当前视图的中心
}
调用闭包中这里一开始会觉得这里可能会有一个循环引用链
self->view->testView->block->self
但是我们进入源码查看
// 进入makeConstraints
public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.makeConstraints(item: self.view, closure: closure)
}
// 进入makeConstraints
internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
let constraints = prepareConstraints(item: item, closure: closure)
for constraint in constraints {
constraint.activateIfNeeded(updatingExisting: false)
}
}
// 进入makeConstraints
internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
let maker = ConstraintMaker(item: item)
closure(maker)
var constraints: [Constraint] = []
for description in maker.descriptions {
guard let constraint = description.constraint else {
continue
}
constraints.append(constraint)
}
return constraints
}
从这里可以看出closure虽然有强引用对象,但是其并没有被调用对象所持有,它在内部直接调用完毕后就释放掉.所以没有造成循环引用,平时开发过程中也就无需进行处理了
进入Masonry源码查看中
image.png
我理解的是这里的block属于栈上管理,并没有调用copy方法也没有强指针引用,所以当block出了作用域就会被销毁,有点类似于swift的逃逸闭包,所以并不存在循环引用问题,我们常见的动画操作应该也是如此
网友评论