生物科技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

相关文章