Swift UITableView重新加载时出现未知崩溃

时间:2015-04-11 11:41:14

标签: ios uitableview swift parse-platform

我有一个包含两个部分的tableview控制器。第一个是立即加载的,总是只有一行,而第二个包含从Parse异步下载的对象。无论我尝试什么,我总是会遇到一些未知错误,在尝试重新加载tableview时会崩溃我的应用程序。我设置了一个异常断点,它在reloadData调用/ reloadSections上触发。如果我评论这一行它可以正常工作,但显然不会更新。我试过了:

  • reloadData和reloadSections
  • 在viewDidLoad中加载对象。
  • 在viewDidAppear中加载对象。
  • 在主线程上使用dispatch_async加载对象。
  • 在两个主线程之后使用dispatch_after加载对象 秒。
  • 主线程上的reloadData和reloadSections。
  • 我还验证了请求成功执行。

我正在使用Swift 1.2和Xcode 6.3

以下是我获取对象的代码:

  var classes = [PFObject]()
  override func viewDidLoad() {
    super.viewDidLoad()
    let relation = user.relationForKey(classesKey)
    let query = relation.query()
    query!.findObjectsInBackgroundWithBlock { (results: [AnyObject]?, error: NSError?) -> Void in
      if let error = error {
        println(error.localizedDescription)
      } else {
        self.classes = results as! [PFObject]
        dispatch_async(dispatch_get_main_queue()) {
          self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
        }
      }
    }
  }

这是我的tableViewDataSource实现:

  override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 2
  }

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
      return 1
    case 1:
      return self.classes.count
    default:
      assert(false, "ERROR: Bad Section")
      return 0
    }
  }

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCellWithIdentifier(self.reuseIdentifier) as? UITableViewCell
    if (cell == nil) {
      cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
    }
    switch section {
    case 0:
      cell?.textLabel?.text = (self.mode == LXMode.Learn) ? "Add Classes You Need Help With" : "Add Classes You Want to Tutor"
    case 1:
      let classObject = self.classes[indexPath.row]
      cell?.textLabel?.text = classObject.objectForKey("name") as? String
      cell?.detailTextLabel?.text = classObject.objectForKey("departmentPrefix") as! String + "-" + String(classObject.objectForKey("number") as! Int)
    default:
      assert(false, "ERROR: Bad Section")
      break
    }
    return cell!
  }

知道可能导致这种情况的原因吗?

3 个答案:

答案 0 :(得分:0)

您是否尝试在主线程上调用reloadData

var classes = [PFObject]()
override func viewDidLoad() {
    super.viewDidLoad()
    let relation = user.relationForKey(classesKey)
    let query = relation.query()
    query!.findObjectsInBackgroundWithBlock { (results: [AnyObject]?, error: NSError?) -> Void in
      if let error = error {
          println(error.localizedDescription)
      } else {
        self.classes = results as! [PFObject]

        dispatch_async(dispatch_get_main_queue()) {
            self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
         }
      }
   }
}

答案 1 :(得分:0)

我终于明白了 - 我的代码没有任何问题。相反,界面在故事板中搞砸了。当我删除它并重新创建它时,它终于奏效了。

答案 2 :(得分:-3)

您似乎正在尝试从后台线程重新加载UITableView。 UIKit只允许从主线程访问控件并抛出异常。您可以使用Grand Central Dispatch(GCD)编组回主线程。

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
}

您将使用任何UIKit类遇到此问题,并且必须始终从主线程调用它们。文档是GCD的一个很好的参考:

https://developer.apple.com/library/prerelease/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html