Swift inout关键字

2022-06-11  本文已影响0人  Yimmm

作者想要达到的实现:在Swift组件化搭建中,让属性传给闭包作为参数供外部Model构建函数使用,使用时在外部修改闭包参数就可以对类中属性修改,从而达到使用一个构建函数就可以做到初始化。
解决方案:使用inout关键字修饰函数(闭包)参数,就可以让参数以地址的方式传递,而不是值的方式传递。

首先知道参数在函数中的两种传递方式:

inout关键字基础使用:

// inout关键字
class inoutTest: NSObject {
        
    func changeNum(_ number: Int) {
        // 如果直接修改参数,是会报错 Left side of mutating operator isn't mutable: 'number' is a 'let' constant
        // 因为参数传的是值,而不是内存地址
        number += 1
    }
}

// 添加inout关键字修饰参数
class inoutTest: NSObject {
    
    func changeNum(_ number: inout Int) {
        
        number += 1
    }
}
简单引用例子:
class TestViewController: UIViewController {
    var num: Int = 0
    // 点击测试
    func clickToTest() {
        
        let testClass = inoutTest()
        // 因为用了inout关键字修饰,这里传参时得用&num传属性内存地址
        testClass.changeNum(&num)
        // 打印测试
        print("YYY = \(num)")
    }

}

运行后调用clickToTest ()方法,控制台打印出来YYY = 1

———————————————我是分割线———————————————

知道了这个inout关键字的作用之后,就能解决一个通用的初始化构造函数完成必要的初始化啦!!!

1. 使用inout关键字修饰闭包参数:
import UIKit
/// 构建CollectionView的Model类
class VEBBaseCollectionViewModel: NSObject {
    
    /// 构建函数参数闭包
    public typealias cellModelsClosure = (inout [VEBBaseCollectionViewCellModel]) -> Void

    /// 数据源
    var cellModels = [VEBBaseCollectionViewCellModel]()
    
    init(cellModelsClosure: cellModelsClosure) {
        // 闭包inout修饰参数&cellModels,传的是数据源cellModels的内存地址
        cellModelsClosure(&cellModels)
    }
    
}

(inout [VEBBaseCollectionViewCellModel]) -> Void 其中使用inout修饰[VEBBaseCollectionViewCellModel]后,我们只需要传一个符合该类型的属性地址,就可以在外部构建函数中以参数方式修改数据源。

2. 其中VEBBaseCollectionViewCellModel的代码:
/// 构建CollectionViewCell的基础属性Model类
class VEBBaseCollectionViewCellModel: NSObject {
    
    /// Cell类名
    var cellClass: String!
    /// 标题
    var fieldTitle: String!
    /// 副标题
    var fieldSubTitle: String!
    /// 图片名
    var imageName: String!
    /// 图片URL
    var imageURL: String!
    /// 辅助字段
    var others: [String]!
    /// 是否只可读
    var isReadOnly: Bool!
    
    override init() {
        super.init()
    }
    
}

3.在适当处调用Model的构建函数
    /// 规定的通用组件构建类
    override func setCollectionCellModel() {
        
        let viewModel = VEBBaseCollectionViewModel { cellModels in
            
            let cellModel = VEBBaseCollectionViewCellModel()
            // 实现去model化开发组件,无业务代码嵌入,可以轻松重用各类基础Cell
            cellModel.cellClass = "VEBBookCoverStyle1CollectionViewCell"
            cellModel.fieldTitle = "标题名字"
            cellModel.imageURL = "图片的URL"
            // 这里的cellModels是闭包参数,可以直接修改到类中的属性
            cellModels.append(cellModel)
        }
    }

这样就能实现一个构建函数完成所需的初始化,简单易用,使用时还有提示构建所需要的参数。


构建函数
上一篇 下一篇

猜你喜欢

热点阅读