【问题标题】:How to properly use Realm objects in a UITableViewController?如何在 UITableViewController 中正确使用 Realm 对象?
【发布时间】:2015-04-05 10:22:12
【问题描述】:

我试图在我的 UITableViewController 中使用 Realm,如果我将对象转换为它的类,每当我尝试在行索引处查找对象时都会遇到问题(如果我使用了错误的术语,请原谅我,我对 Swift、Realm 和 iOS 开发者还是很陌生!)...

我有一个看起来像这样的Site 类,并且数据库有几千个条目:

class Site: RLMObject {
    var id: String = ""
    var name: String = ""
}

在我的表格视图控制器中,当我尝试根据结果集中的索引获取Site 以加载到单元格中时,如果我尝试将其转换为Site 对象,它总是为零!如果我让它使用AnyObject 设置,那么我可以看到确实找到了该索引处的正确站点。

我猜测AnyObject 上的.name 调用只是因为AnyObject 响应.name 而起作用,但它帮助我看到索引是正确的并且该站点确实存在...

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    let allSites = Site.allObjects()
    var any: AnyObject = allSites.objectAtIndex(UInt(indexPath.row))
    var site = allSites.objectAtIndex(UInt(indexPath.row)) as? Site
    println("With AnyObject: \(any.name)")
    println("With casting: \(site?.name)")

    return cell
}

上面打印语句的结果如下所示(例如在名为“Addeboda”的网站上):

With AnyObject: Addeboda
With casting: Optional("")

我做错了吗?我用谷歌搜索了一下,我能找到的所有类似的教程和答案都表明results.objectAtIndex(index) as Class 应该是正确的方法。

【问题讨论】:

    标签: ios swift realm


    【解决方案1】:

    无需演员表

    似乎不需要投射到站点。这工作正常:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let allSites = Site.allObjects()
        let site: AnyObject! = allSites[UInt(indexPath.row)]
    
        cell.textLabel!.text = site.name
    
        println("Site is: \(site.id)")
    
        return cell
    }
    

    似乎是 Swift 或 Realm 的一个错误。我猜他们中的一个人在将AnyObject! 向下转换为某事时会感到困惑。

    用正确的类型初始化一个新实例

    但是,如果您确实需要使用Site 模型类,您可以从结果中初始化一个新的RLMObject

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let allSites = Site.allObjects()
        let site = Site(object: allSites[UInt(indexPath.row)])
    
        cell.textLabel!.text = site.name
    
        println("Site is: \(site.id)")
    
        return cell
    }
    

    第一次尝试

    很遗憾听到您在使用 Realm 和 Swift 时遇到问题。我绝不是 Swift 专业人士,但看起来您正在将 site 转换为可选项,并且使用可选项转换运算符 site?.name 的结果也是可选项。因此得到Optional("")

    你能试试看你在以下方面是否有更好的运气?

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let allSites = Site.allObjects()
    
        if var site = allSites[UInt(indexPath.row)] as? Site {
            println("Site is: \(site.name)")
        } else {
            println("it not castable to Site. It is: \(toString(allSites[UInt(indexPath.row)].dynamicType))")
        }
    
        return cell
    }
    

    另外,您可以使用yourObject.dynamicType 来获取对对象真实类类型的引用。

    祝你好运

    【讨论】:

    • 当您第一次调用site.name 时,它会在尝试解开可选值时引发异常。
    • 非常好,Site(object: allSites[UInt(indexPath.row)]) 工作!不过,它确实需要铸造。 AnyObject 有一个 name 函数使 site.name 工作是偶然的。尝试使用site.idAnyObject 上引发了一个异常......
    • 你确定吗?当我拥有var site: AnyObject! = ... 并将属性重命名为lolIdlolName 时,该方法仍然有效......
    • 是的,它使构建失败并说“'AnyObject' 没有名为 'id' 的成员”
    【解决方案2】:

    这是来自tableview sample project的一些代码:

    class TableViewController: UITableViewController {
    
        var array = DemoObject.allObjects().sortedResultsUsingProperty("date", ascending: true)
        ...
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as Cell
    
            let object = array[UInt(indexPath.row)] as DemoObject
            cell.textLabel?.text = object.title
            cell.detailTextLabel?.text = object.date.description
    
            return cell
        }
    }
    

    您应该能够在存储该 indexPath.row 对象的行上进行转换

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多