航天科技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

发表评论

电子邮件地址不会被公开。 必填项已用*标注