• swift协议代理的使用以及解决循环引用问题


     

    这两天看了一下swift的协议代理, 大体思路和OC没什么区别, 但是按照官方的书本写出的协议代理, 发现会有内存泄露问题, 找了半天没有发现问题, 突然想起看系统类的协议代理的写法, 瞬间发现了问题, 不多废话了, 下面是代码.
    我建了一个single View application, 为了验证内存泄露, 我保留了xcode所给的viewController.swift,在storyboard中viewController前添加了一个 navigationController, 并且自己建了两个视图控制器: VC1.swift 和 VC2.swift, 由viewController 跳转至 VC1, 在VC1中设置delegate, 再跳转到VC2, 让VC2改变VC1的背景颜色, 然后一直返回到viewController, 看VC1 和 VC2 是否释放了内存;
    下面这是我的storyboard, 我在viewContronller 前面添加了一个navigationController:
    这是我的Main.storyboard

    下面是我的viewController里的代码:

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.title = "viewController"
    
            //实例化一个button, 添加点击事件
            let button = UIButton(type: UIButtonType.Custom)
            button.backgroundColor = UIColor.redColor()
            button.setTitle("点击跳转到VC1", forState: UIControlState.Normal)
            button.frame = CGRectMake(100, 100, 150, 100)
            button.addTarget(self, action: "buttonClicked", forControlEvents: UIControlEvents.TouchUpInside)
            self.view.addSubview(button)
        }
    
        //跳转到VC1
        func buttonClicked(){
            let vc_1 = VC1()
            self.navigationController?.pushViewController(vc_1, animated: true)
        }
    }
    
    

    这下面是VC1 中的代码:

    import UIKit
    
    // VC1 遵守changeColor协议, 并且实现协议中的方法
    class VC1: UIViewController, changeColor{
    
        var vc_2: VC2?   //定义一个VC2变量
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.orangeColor()
            self.title = "VC1"
    
            //实例化VC2, 并且设置delegate
            vc_2 = VC2()
            vc_2?.delegate = self
    
            let button = UIButton(type: UIButtonType.Custom)
            button.backgroundColor = UIColor.whiteColor()
            button.setTitle("点击跳转到VC2", forState: UIControlState.Normal)
            button.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
            button.frame = CGRectMake(100, 100, 150, 100)
            button.addTarget(self, action: "VC1buttonClicked", forControlEvents: UIControlEvents.TouchUpInside)
            self.view.addSubview(button)
        }
    
        //跳转到VC2
        func VC1buttonClicked(){
            self.navigationController?.pushViewController(vc_2!, animated: true)
        }
    
        //实现协议中的方法
        func changeColorWithColor(color color: UIColor) {
            self.view.backgroundColor = color
        }
    
        deinit{
            print("vc_1 的内存已释放 !")
        }
    }
    
    

    下面是我的VC2中的代码:

    import UIKit
    
    //声明一个协议, 让其继承(我也不知道该不该叫继承, 然而在这里并不重要) NSObjectProtocol, 只有这样才能在设置代理的时候前面添加weak
    protocol changeColor: NSObjectProtocol {
        func changeColorWithColor(color color: UIColor)
    }
    
    class VC2: UIViewController {
    
        //注意这里: changeColor为协议名, delegate前面必须有weak修饰, 如果没有weak修饰就会造成内存泄露, 而可以加weak的前提是, 这个协议必须继承 NSObjectProtocol, 这是我试验出来的, 目前来看, 应该是这样的
        weak var delegate: changeColor?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.whiteColor()
            self.title = "VC2"
    
            let button = UIButton(type: UIButtonType.Custom)
            button.backgroundColor = UIColor.redColor()
            button.setTitle("点击改变VC1的背景颜色", forState: UIControlState.Normal)
            button.frame = CGRectMake(100, 100, 200, 100)
            button.addTarget(self, action: "VC1buttonClicked", forControlEvents: UIControlEvents.TouchUpInside)
            self.view.addSubview(button)
        }
    
        func VC1buttonClicked(){
            //使用代理调用协议声明并且VC1已经实现的方法
            self.delegate?.changeColorWithColor(color: UIColor.cyanColor())
        }
    
        deinit{
            print("vc_2的内存已经释放 !")
        }
    }
    
    

    下面是返回至viewController后的打印信息:

    /*
    vc_1 的内存已释放 !
    vc_2的内存已释放 !
    */
    
  • 相关阅读:
    EV录屏
    Oracle 游标详解 【转载至CSDN「鱼丸丶粗面」】
    ORACLE查询表数据占用存储空间大小(清理表碎片)
    开源项目
    Shiro 简介(认证、授权、加密、会话管理、与 Web 集成、缓存等)
    OSCHINA 公布 2019 年度最受欢迎中国开源软件
    腾讯开发者手册
    hutool JAVA 工具类
    小程序登录
    微信小程序button组件样式
  • 原文地址:https://www.cnblogs.com/luoxiaoxi/p/5362300.html
Copyright © 2020-2023  润新知