科技美学Xcode8调试黑科技:Memory Graph实战解决闭包引用循环问题

Xcode8的调剂技能又追加了一个黑科技:Memory
Graph。简单的游说就是是可以以运转时将内存中的目标十分成一摆图。在实地的开发者听到了之消息不时鸣了雷鸣般的掌声!我们来探视前方记者发回之现场照:

妈妈说再度为未用担心引用循环啦!除非你是单瞎子。

那通过一个实际项目来练习一下咔嚓。
首先我们描绘了一个自定义UIView:MyView。初始化的时光收一个不曾参数为从不返回值的闭包作为参数,并存为温馨之特性:

typealias Action = () -> Void

class MyView: UIView {

    var action: Action?

    init(action: @escaping Action) {
        self.action = action
        super.init(frame: CGRect.zero)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

紧接着我们于一个ViewController中初始化MyView,并且也保留也性:

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    var myView: MyView?

    override func viewDidLoad() {
        super.viewDidLoad()
        myView = MyView(action: testMethod)
    }

    func testMethod() {
        label.text = "haha"
    }

}

就vc的view上发出一个label控件,在viewDidLoad时初始化myView,并且以自家之一个testMethod方法当参数传于了myView。
testMethod中安了自身label的text。
专注,划重点了!

此处反映了swift函数式的表征:函数可以任意的当作一个变量传递。

斯例子影射里开发中一个广的景:一个tableViewCell中生一个去按钮,通过闭包将艺术传进,cell保存之闭包;另一方面是闭包被调起后,删除某条数后刷新数据源。

那么这样形容会生出引用循环为?

    func testMethod() {
        label.text = "haha"
    }

骨干在当时段代码上,一个类似的法子里装本身的特性,会捕捉这个特性为?这个地方得写self,但是捕捉策略是unowned还是strong呢?
本条闭包的落实是未能够和谐声明捕捉策略的:

遂就来说明一下。运行起来后,push这个ViewController后pop出去(记得要拓展简单不行,好像只是来一致不善Xcode有时不见面启动分析)。
继之点击是按钮:

这个时就是进去了断点模式,可以查issue面板,注意选择右边Runtime:

起诸多叹号说明就是产生题目了。看内存中object的讳,有一样长达是Closure captures
leaked。展开后点击就可以看到之issue对应的内存图形展示在中间的面板中。
当然了,我们更多之时光是在debug页面下查看:

瞩目到我们刚刚底靶子名:一个给MyView,一个给ViewController。我们pop了少数不善,按理说内存里不该产生这点儿独对象,然而要生些许客实例。所以,这中引用循环了。点击紫色的叹号会产出Xcode分析出来的内存引用图形:

有了是图虽异常易看下了:myView保持了action,action保持了testMethod,testMethod中盖安了vc的label所以也保持了VC。所以我们得确定:术被隐式的self的捕捉策略是strong。这样直接将方传入子view中见面唤起引用循环。

釜底抽薪方案

1.拿逻辑实现在一个匿名闭包里,不兑现在类的法门及

这般就足以友善声明捕捉策略。这样的方使用就跟OC的block类似了:

        myView = MyView(){ [unowned self] in
            self.label.text = "haha"
        }

2.每当匿名闭包中调用方法

未是直传入testMethod方法,而是以传出的闭包中调用自身之艺术:

        myView = MyView(){ [unowned self] in
            self.testMethod()
        }

迎接关注自我的微博:@没故事之卓同学

系链接:
WWDC 2016 Session 410 Visual Debugging with
Xcode