Ios 通用UITableView和NSFetchedResultsController,继承自UITableViewDelegate、UITableViewDataSource和NSFetchedResultsController

Ios 通用UITableView和NSFetchedResultsController,继承自UITableViewDelegate、UITableViewDataSource和NSFetchedResultsController,ios,swift,uitableview,core-data,Ios,Swift,Uitableview,Core Data,我正在尝试起草一个可重用类,它基本上可以重用到具有几乎相同实现的多个实体。 基本上,我将有几个UIViewController,每个都包含UIView,其中包含UIView及其自定义参数,用于由同一managedObjectContext管理但具有可重用NSFetchedResultsController的不同实体 第一个问题:我的方法是保留UITableView的循环吗?因此我在从CoreManager继承的委托类中使用了弱var tableView:UITableView,它将在UIView

我正在尝试起草一个可重用类,它基本上可以重用到具有几乎相同实现的多个实体。 基本上,我将有几个UIViewController,每个都包含UIView,其中包含UIView及其自定义参数,用于由同一managedObjectContext管理但具有可重用NSFetchedResultsController的不同实体

第一个问题:我的方法是保留UITableView的循环吗?因此我在从CoreManager继承的委托类中使用了弱var tableView:UITableView,它将在UIView中使用实现的UITableView进行初始化,以处理TableViewDataSource中的所有不变性。我对这种方法有疑问,我想就如何实现它提供一些指导,这样我就不会引入内存泄漏

第二个问题:在我的TableViewManager类中,基本上我将尝试显式实现最终将出现在自定义UIView中的自定义代码,而且我不确定这是否是一种好方法

注意:请原谅我有限的经验,下面的代码只是一个草稿,不完整

与问题二相关的以下和以上代码


从概念上讲,这看起来还不错,但是如果没有更多的上下文,代码可能有点难以理解。如果您添加了使用这个类的方式,静态部分是什么,以及应该更改哪些部分,这会有所帮助

只要表视图本身不访问其所有者类,表视图就不需要很弱。我相信在你的情况下,它不会访问它

我希望你们有这样一个接口,通过构造函数来完成静态部分。例如,您可以:

TableViewManager {
    let tableView: UITableView
    let fetchResultController: NSFetchedResultsController

    init(tableView: UITableView, fetchResultController: NSFetchedResultsController) {
        self.tableView = tableView
        self.fetchResultController = fetchResultController
    }
}
从接口的角度来看,这对于静态部分来说已经足够了。您可以在类中设计节和单元,同时处理删除、插入等操作

那么您的视图控制器可能看起来像

class MyViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    var tableViewManager: TableViewManager?

    override func viewDidLoad() {
        super.viewDidLoad()
        tableViewManager = TableViewManager(tableView: tableView, fetchResultController: MyManagedObject.buildFetchResultController(...))
    }

}
当然,现在缺少了动态部分。我会创建自定义代理,如:

   override func viewDidLoad() {
       super.viewDidLoad()
       tableViewManager = TableViewManager(tableView: tableView, fetchResultController: MyManagedObject.buildFetchResultController(...))
       tableViewManager.delegate = self
   }

extension MyViewController: TableViewManagerDelegate {
    // ... all the dynamic part goes in here
}
但您也可以使用TableViewManager的子类,或者注入一些其他类、数据提供程序和控制器。。。这里的选择完全属于你

所以要回答第一个问题:不,在类和表视图之间不应该有retain循环,所以不需要弱引用


但第二个问题完全是基于观点的。我能给你的最好建议是从界面开始。首先设计您希望如何从外部使用您的工具,然后在其中构建逻辑。

谢谢您的回答,您让我走上了正确的道路。基本上我是想实现你的建议。我对它进行了初步测试,它正按照我的预期工作我确认了你的回答。
class TableViewManager: TVDelegation, TableViewManagerDelegate {
    //FIXME: Implement deleting
    func handleDelete(at indexPath: IndexPath) {
    }
    //FIXME: Implement Actions
    func handleSwipeAction(at indexPath: IndexPath) -> UISwipeActionsConfiguration{
        let action = UIContextualAction(style: .normal, title: "Action", handler: { [weak self] action, view, completion in
                completion(true)
            })
        let configuration = UISwipeActionsConfiguration(actions: [action])
        return configuration
    }
}
class TVDelegation: TableViewDataSource, UITableViewDelegate{
    weak var delegateManager : TableViewManagerDelegate?
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if let sections = fetchedResultsController.sections {
            let currentSection = sections[section]
            return currentSection.name
        }
        return nil
    }
    //FIXME: - IMPLEMENT NAVIGATION TO DETAILCONTROLLER
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        fetchedResultsController.object(at: indexPath)
        tableView.reloadRows(at: [indexPath], with: .automatic)
        tableView.deselectRow(at: indexPath, animated: true)
    }
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
       let deleteAction = UIContextualAction(style: .destructive, title: "") {[weak self]  action, view , completion in
            self?.delegateManager?.handleDelete(at: indexPath)
            completion(true)
        }
        deleteAction.image = UIImage(named: "trash")?.withRenderingMode(.alwaysTemplate)
        let swipeConfig = UISwipeActionsConfiguration(actions: [deleteAction])
        return swipeConfig
    }
    func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        return delegateManager?.handleSwipeAction(at: indexPath)
    }
}
TableViewManager {
    let tableView: UITableView
    let fetchResultController: NSFetchedResultsController

    init(tableView: UITableView, fetchResultController: NSFetchedResultsController) {
        self.tableView = tableView
        self.fetchResultController = fetchResultController
    }
}
class MyViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    var tableViewManager: TableViewManager?

    override func viewDidLoad() {
        super.viewDidLoad()
        tableViewManager = TableViewManager(tableView: tableView, fetchResultController: MyManagedObject.buildFetchResultController(...))
    }

}
   override func viewDidLoad() {
       super.viewDidLoad()
       tableViewManager = TableViewManager(tableView: tableView, fetchResultController: MyManagedObject.buildFetchResultController(...))
       tableViewManager.delegate = self
   }

extension MyViewController: TableViewManagerDelegate {
    // ... all the dynamic part goes in here
}