【问题标题】:iOS realm Results<Object> can't add Results<Project>iOS 领域 Results<Object> 无法添加 Results<Project>
【发布时间】:2017-04-29 12:07:09
【问题描述】:

我尝试为领域结果创建通用 UITableView 数据源类,但是当我尝试发送与 示例结果中的结果对象> 我收到此错误消息:

无法将'Results''类型的值转换为预期的元素类型'Results''

class RealmResultsTableViewDataSource: TableViewDataSource {

var realmResults:[Results<Object>]
var notificationTokens: [NotificationToken] = []

init(tableView: UITableView, realmResults: [Results<Object>], configCell: @escaping TableViewConfigCellBlock, canEdit: TableViewCanEditCellBlock?, canMove: TableViewCanMoveRowBlock?, commitEditing: TableViewCommitEditingStyleBlock?) {

    self.realmResults = realmResults

    super.init(tableView: tableView, dataSource: [], configCell: configCell, canEdit: canEdit, canMove: canMove, commitEditing: commitEditing)

    addTokens(for: realmResults)
}

deinit {
    for token in notificationTokens {
        token.stop()
    }
}

override var sections: Int{
    get { return realmResults.count }
}

override func numberOfRows(section: Int) -> Int {
    return realmResults[section].count
}

// MARK: Add tokens

func addTokens(for results: [Results<Object>]) {
    for result in results {

       let notificationToken = result.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
            guard let tableView = self?.tableView else { return }
            switch changes {
            case .initial:
                // Results are now populated and can be accessed without blocking the UI
                tableView.reloadData()
                break
            case .update(_, let deletions, let insertions, let modifications):
                // Query results have changed, so apply them to the UITableView
                tableView.beginUpdates()
                tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
                                     with: .automatic)
                tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                tableView.endUpdates()
                break
            case .error(let error):
                // An error occurred while opening the Realm file on the background worker thread
                fatalError("\(error)")
                break
            }
        }

        notificationTokens.append(notificationToken)
    }
}

override func dataSourceObject(on indexPath: IndexPath) -> Any {

    return realmResults[indexPath.section][indexPath.row]
}

}

还有:

让领域=尝试!领域()

    let result = realm.objects(Project.self).filter("id < 10").sorted(byKeyPath: "id", ascending: true)

    tableViewDataSource = RealmResultsTableViewDataSource(tableView: tableView, realmResults: [result], configCell: { (tableView, indexPath, object) -> UITableViewCell in

        let cell = tableView.dequeueReusableCell(withIdentifier:ProjectListTableViewCell.cellIdentifier , for: indexPath)

        return cell

    }, canEdit: nil, canMove: nil, commitEditing: nil)



import RealmSwift

class Project: Object {

    dynamic var id: Int = 0
    dynamic var name: String = ""
}

解决方案:

class RealmResultsTableViewDataSource<T: Object>: TableViewDataSource {

    var realmResults:Results<T>
    var notificationTokens: [NotificationToken] = []


    init(tableView: UITableView, realmResults: Results<T>, configCell: @escaping TableViewConfigCellBlock, canEdit: TableViewCanEditCellBlock?, canMove: TableViewCanMoveRowBlock?, commitEditing: TableViewCommitEditingStyleBlock?) {

        self.realmResults = realmResults

        super.init(tableView: tableView, dataSource: [], configCell: configCell, canEdit: canEdit, canMove: canMove, commitEditing: commitEditing)


        addTokens(for: self.realmResults)
    }

    deinit {

        for token in notificationTokens {
            token.stop()
        }
    }

    override var sections: Int{

        get{
          return 1
        }
    }

    override func numberOfRows(section: Int) -> Int {
        return realmResults.count
    }


    // MARK: Add tokens

    func addTokens(for results: Results<T>) {

           let notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
                guard let tableView = self?.tableView else { return }
                guard tableView.dataSource === self else { return }
                switch changes {
                case .initial:
                    // Results are now populated and can be accessed without blocking the UI
                    tableView.reloadData()
                    break
                case .update(_, let deletions, let insertions, let modifications):
                    // Query results have changed, so apply them to the UITableView
                    tableView.beginUpdates()
                    tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
                                         with: .automatic)
                    tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
                                         with: .automatic)
                    tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
                                         with: .automatic)
                    tableView.endUpdates()
                    break
                case .error(let error):
                    // An error occurred while opening the Realm file on the background worker thread
                    fatalError("\(error)")
                    break
                }
            }

            notificationTokens.append(notificationToken)
    }

    override func dataSourceObject(on indexPath: IndexPath) -> Any {

        return realmResults[indexPath.row]
    }

    override func removeObject(indexPath: IndexPath) {
       // assertionFailure("you can use ramoveObject int \(String(describing: self))")
    }

}

【问题讨论】:

  • 请改进您的代码格式。这样你会得到更好的答案...

标签: ios swift3 realm


【解决方案1】:

AFAIK,Realm Swift 还不支持多态。

目前的解决方案是使用组合而不是继承。 关于它有很多很好的论据(四人帮和约书亚 Bloch 提到了这种方法的一些著名支持者)。

另一方面,我们正在考虑允许继承,但它 不允许查询。例如:Animal 由两者扩展 狗、猫和鸭。您将无法使用 for 查询 Animals 腿,有所有的狗和猫,但没有鸭子。我们觉得这将是 一种非常严重的行为,但渴望听取更多意见。

这里讨论(这里讨论产品的java版本,所以这只是你的一个起点......):https://github.com/realm/realm-java/issues/761

最简单的解决方案[但如果您需要将这些方法与 Object 的其他子类重用,可能不是最好的],因为您将替换 “对象”与“项目”

【讨论】:

  • 感谢您的帮助,我设法使用泛型类找到了解决方案
  • 太棒了!很高兴你回到正轨!
猜你喜欢
  • 2018-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多