2015-04-11 3 views
-1

У меня есть контроллер таблицы с двумя разделами. Первый загружается немедленно и всегда имеет только одну строку, а вторая содержит объекты, загруженные из Parse асинхронно. Независимо от того, что я пытаюсь, я всегда получаю неизвестную ошибку, которая приводит к сбою моего приложения при попытке перезагрузить tableview. Я установил контрольную точку исключения, и она запускается в reloadData call/reloadSections. Если я прокомментирую эту строку, она отлично работает, но, очевидно, не обновляется. Я пробовал:Swift UITableView Неизвестный сбой при перезагрузке

  • 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! 
    } 

Любой идея, что может быть причиной этого?

+0

Вместо того, чтобы перезагружать только раздел, попробуйте перезагрузить весь вид таблицы и поместите точку останова в cellForRowAtIndexPath & numberOfRowsInSection. И попытайтесь выяснить причину аварии. Пока вы это делаете, проверьте, находитесь ли вы в основном потоке или нет. –

+0

Привет @KumarNitin, я попробовал это. После вызова всех соответствующих методов делегирования происходит сбой. – AttilaTheFun

+0

Что означает «некоторая неизвестная ошибка»? – nhgrif

ответ

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) 
     } 
     } 
    } 
} 
+0

Привет, Dan, я пробовал это также с reloadSections и reloadData и имел тот же результат с обоими. – AttilaTheFun

+0

Хотя верно, что вы можете обновлять пользовательский интерфейс только в основном потоке, 'reloadData' не обновляет пользовательский интерфейс. Более того, ни один из методов 'UITableViewDelegate' фактически не обновляет пользовательский интерфейс.Яблочный код в представлении таблицы - это то, что фактически обновляет табличное представление, и я был бы чрезвычайно удивлен, если Apple разрешало этому потоку зависать от того, на какой поток вы назвали 'reloadData' (вместо того, чтобы заставлять его в основной поток) , – nhgrif

-3

Похоже, что вы пытаетесь перезагрузить UITableView из фонового потока. UIKit разрешает доступ к элементам управления из основного потока и генерирует исключение. Вы можете использовать Grand Central Dispatch (GCD), чтобы вернуться к основному потоку.

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

Вы столкнетесь с этим с любыми классами UIKit и должны всегда вызывать их из основного потока. Документы являются хорошим ориентиром для НОДА:

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

+0

Привет @jblair! Спасибо за предложение. Но я попробовал это как с reloadSections, так и с reloadData и имел тот же результат. – AttilaTheFun

+0

@AttilaTheFun Возможно, вы получаете «NSInternalInconsistencyException»? Если это так, это обычно результат вашего источника данных UITableView, который не соответствует вашим запрошенным изменениям в таблице. Например, ваш источник данных описывает только один раздел (индекс 0), и вы сообщаете таблице обновить второй (индекс 1), который фактически не существует. –

+0

Хотя верно, что вы можете обновлять пользовательский интерфейс только в основном потоке, 'reloadData' не обновляет пользовательский интерфейс. Более того, ни один из методов 'UITableViewDelegate' фактически не обновляет пользовательский интерфейс. Яблочный код в представлении таблицы - это то, что фактически обновляет табличное представление, и я был бы чрезвычайно удивлен, если Apple разрешало этому потоку зависать от того, на какой поток вы назвали 'reloadData' (вместо того, чтобы заставлять его в основной поток) , – nhgrif

0

я, наконец, понял это - не было ничего плохого с моим кодом. Скорее, интерфейс был испорчен в раскадровке. Когда я удалил его и воссоздал, он наконец-то сработал.

Смежные вопросы