swift5 闭包属性应用 和 循环引用问题及测试

1,570 阅读1分钟

swift闭包的功能很强大。如果block不在当前方法执行,就用一个属性记录它,在需要的时候调用这个属性就可以了。

定义闭包属性:

EmoticonView.swift

/// 选中表情回调
    private var selectedEmoticonCallBack: (_ emoticon: Emoticon)->()

如果闭包没有设置为可选项,就需要自定义构造函数创建闭包属性:

先记录闭包属性,再进行接下来的设置

EmoticonView.swift

    // MARK: - 构造函数
    init(selectedEmoticon: @escaping (_ emoticon: Emoticon)->()) {
        // 记录闭包属性
        selectedEmoticonCallBack = selectedEmoticon
        // 调用父类的构造函数
        var rect = UIScreen.main.bounds
        rect.size.height = 226
        super.init(frame: rect)
        backgroundColor = UIColor.white
        setupUI()
        // 滚动到第一页
        let indexPath = NSIndexPath(item: 0, section: 1)
        
        DispatchQueue.main.async {
            self.collectionView.scrollToItem(at: indexPath as IndexPath, at: .left, animated: false)
        }
    }

设置闭包内容

ViewController.swift

    /// 表情键盘视图
    private lazy var emoticonView: EmoticonView = EmoticonView { [weak self] (emoticon) -> () in
        //闭包里面出现self小心循环引用
        self?.insertEmoticon(em: emoticon)
//        self?.textView.text = emoticon.chs
    }
    /// 插入表情符号
    /// - parameter em: 表情模型
    func insertEmoticon(em: Emoticon) {
        textView.text = em.chs
    }

传递参数,执行回调:

EmoticonView.swift

//MARK: - 代理方法
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//        print(indexPath)
        // 获取表情模型
        let em = packages[indexPath.section].emoticons[indexPath.item]
        // 执行`回调`
        selectedEmoticonCallBack(em)
    }

循环引用问题

(self)控制器强引用emoticonView----emoticonView里面定义闭包属性-----VC强引用闭包

闭包强引用self

形成循环引用问题,解决:[weak self]

class ViewController: UIViewController {
/// 表情键盘视图
    private lazy var emoticonView: EmoticonView = EmoticonView { [weak self] (emoticon) -> () in
        //闭包里面出现self小心循环引用
        self?.insertEmoticon(em: emoticon)
//        self?.textView.text = emoticon.chs
    }
    ...................}

测试循环引用问题:

在当前控制器写:

deinit {
        print("888")
    }

在当前控制器之前,加上navigationController,来测试