UITableView пустой после reloadData() из NSNotificationCenter
У меня проблема с моим UITableView. Это всегда пусто.
Аннотация: у меня есть модельный класс. После создания экземпляра модели в методе viewDidLoad в моем UITableViewController он будет асинхронно получать JSON-структуру с моего сервера. Эти данные будут разбираться с моим объектом.
Мой UITableViewController также имеет NSNotification Observer с методом селектора. Этот метод селектора будет запущен, если класс модели отправит уведомление (отправит уведомление, если модель завершит запрос и анализ данных с сервера).
Метод селектора выполнит "self.tableView.reloadData()" в блоке главной очереди отправки.
Отладчик показывает, что объект не ноль, но tableView пуст. У меня нет идеи, почему табличное представление пусто.
Части из моего UITableViewController:
import UIKit
Класс BillingPlanTableViewController: UITableViewController {
@IBOutlet weak var menuButton: UIBarButtonItem!
var budgetBillingPlansModel: BudgetBillingPlanModel!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
//Menu gesture recognizer
if self.revealViewController() != nil {
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
//initialize BudgetBillingPlansModel
NSNotificationCenter.defaultCenter().addObserver(self, selector: "initBbPDone:",name:"initBbPDone", object: nil)
budgetBillingPlansModel = BudgetBillingPlanModel()
println(budgetBillingPlansModel)
}
// MARK: - Custom Methods
func initBbPDone(notification: NSNotification){
//reload tableview: from in thread: Zu diesem Zeitpunkt ist mein Objekt gefüllt.
dispatch_async(dispatch_get_main_queue(),{
self.tableView.reloadData()
});
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if(self.budgetBillingPlansModel.checkBbPisReady()){
return self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray().count
}else{
return 0
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(self.budgetBillingPlansModel.checkBbPisReady()){
var numberOfRowsInSection: Int = 0
for(var index = 0; index < self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray().count; index++){
if(index == section){
numberOfRowsInSection = self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[index].getSubPlan().count
}
}
return numberOfRowsInSection
}else{
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("budgetBillingPlans", forIndexPath: indexPath) as! BudgetBillingPlanTableViewCell
if(self.budgetBillingPlansModel.checkBbPisReady()){
//section == bbP Array
for(var i = 0; i < self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray().count; i++){
if(i == indexPath.section){
//row == subPlans Array
let subPlans: [SubPlan] = self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getSubPlan()
for(var j = 0; j < subPlans.count; j++){
if(j == indexPath.row){
cell.ibo_header.text = "\(self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getSubPlan()[j].getSbbpDivisionName())"
cell.ibo_budgetAmount.text = "\(self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getSubPlan()[j].getSbbpActAmount())"
cell.ibo_contract.text = "\(self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getSubPlan()[j].getSbbpContractNumber())"
cell.ibo_date.text = (self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getFirstAdjustmentDate()) + " " + (self.budgetBillingPlansModel.getBudgetBillingPlanModel()!.getBbpArray()[i].getbbpCycleName())
}
}
}
}
}else{
}
return cell
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 150
}
}
Детали из моего модельного класса:
class BudgetBillingPlanModel: NSObject {
var budgetBillingPlan: BudgetBillingPlan!
var bbPisReady: Bool!
//getBudgetBillingPlans
private func getBudgetBillingPlans(){
Alamofire.request(.GET, Constants.service_getBudgetBillingPlans)
.responseString { (request, response, jsonString, error) in
println(error)// error ist im debugger-Zeitpunkt == nil
self.budgetBillingPlan = self.parseServerResponse(jsonString!)
self.setbbPisReady()
}
}
//Notifications
private func setbbPisReady(){
self.bbPisReady = true
//object controller has to implement the notification method with "initBbPDone"
NSNotificationCenter.defaultCenter().postNotificationName("initBbPDone", object: nil)
}
//check status
func checkBbPisReady()->Bool{
if(self.bbPisReady == true){
return true
}else{
return false
}
}
//getter
func getBudgetBillingPlanModel()->BudgetBillingPlan?{
if(self.checkBbPisReady()){
return self.budgetBillingPlan
}else{
return nil
}
}
Скриншот отладчика:
Дополнение: Если я попытаюсь запустить tableView со статическими ячейками, он покажет статические ячейки. Но после создания экземпляра в viewDidLoad, когда запускается уведомление, табличное представление пусто. Если я буду взаимодействовать с пустым табличным представлением как жестом панорамирования или касания, я получу ошибку: EXC_bad_Access в приложении appdelegate ( thread1)
1 ответ
Я не обнаружил проблему с шаблоном уведомления для связи mvc, но я думаю, что это была проблема с потоками. Решение состояло в том, что я переключился на шаблон kvc, теперь мой tableView больше не пуст.