swift 5 代理使用 & private 修饰符 VS private 修饰符

539 阅读2分钟

委托者A:设置协议,设置代理属性

代理者B:遵守协议,实现协议方法

委托者A:操控代理者B进行操作

下面的例子,自己是自己的代理 self.delegate = self,但是建议实际开发不要这么干


代理的准备:

1、设置代理协议 PicturePickerCellDelegate(PicturePickerController.swift)

⚠️:有两个@objc都要加(协议前,方法前)

/// PicturePickerCellDelegate 代理
/// 如果协议中包含 optional 的函数,协议需要使用 @objc 修饰
@objc
private protocol PicturePickerCellDelegate: NSObjectProtocol {
    /// 添加照片
    @objc optional func picturePickerCellDidAdd(cell: PicturePickerCell)
    /// 删除照片
    @objc optional func picturePickerCellDidRemove(cell: PicturePickerCell)
}

2、设置代理属性(PicturePickerController.swift)

/// 照片选择 Cell - private修饰类,内部的一切方法和属性,都是私有的
private class PicturePickerCell: UICollectionViewCell {
    /// 照片选择代理
    weak var pictureDelegate: PicturePickerCellDelegate?
    }

代理的使用:

3、添加代理(PicturePickerController.swift)

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        //as! PicturePickerCell 如果会放问到自定义cell的属性才加上
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PicturePickerCellId, for: indexPath) as! PicturePickerCell
        // Configure the cell
        cell.backgroundColor = .red
        // 设置代理
        cell.pictureDelegate = self
        return cell
    }

4、实现代理协议中的方法(PicturePickerController.swift)

// MARK: - PicturePickerCellDelegate
//如果协议是私有的。在实现协议方法时,函数也是私有的
//函数私有的,运行时就无法找到该函数,就没有办法发送消息!
//@objc
extension PicturePickerController: PicturePickerCellDelegate {
    @objc fileprivate func picturePickerCellDidAdd(cell: PicturePickerCell) {
        print("addpic")
    }
    @objc fileprivate func picturePickerCellDidRemove(cell: PicturePickerCell) {
        print("removepic")
    }
}

5、具体使用(PicturePickerController.swift)

private class PicturePickerCell: UICollectionViewCell {
// MARK: - 监听方法
    @objc func addPicture() {
        //picturePickerCellDidAdd? ?使用 避免没有实现代理方法就挂了
        pictureDelegate?.picturePickerCellDidAdd?(cell: self)
        print("add")
    }
    @objc func removePicture() {
        pictureDelegate?.picturePickerCellDidRemove?(cell: self)
        print("remove")
    }
}
// 3. 监听方法
        addButton.addTarget(self, action: #selector(self.addPicture), for: .touchUpInside)
        removeButton.addTarget(self, action: #selector(self.removePicture), for: .touchUpInside)

private 修饰符 VS private 修饰符

1、private 修饰符

只允许在当前类中调用,不包括 Extension 
private 现在变为了真正的私有访问控制 
用 private 修饰的方法不可以被代码域之外的地方访问

2、private 修饰符

fileprivate 其实就是过去的 private。 
其修饰的属性或者方法只能在当前的 Swift 源文件里可以访问。 
即在同一个文件中,所有的 fileprivate 方法属性都是可以访问到的。

具体见: docs.swift.org/swift-book/…

  • File-private access restricts the use of an entity to its own defining source file. Use file-private access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
  • Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file. Use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.

翻译过来:

  • fileprivate 限制实体只能在其定义的文件内部访问。如果功能的部分实现细节只需要在文件内使用时,可以使用 fileprivate 来将其隐藏。

  • private 限制实体只能在其定义的作用域,以及同一文件内的 extension 访问。如果功能的部分细节只需要在当前作用域内使用时,可以使用 private 来将其隐藏。