来自NSNotificationCenter

时间:2015-06-17 09:42:16

标签: swift uitableview tableview reloaddata nsnotification

我的UITableView出了问题。它总是空的。

摘要: 我有一个模特课。在我的UITableViewController中的方法viewDidLoad中实例化模型后,它将从我的服务器异步获取JSON结构。这些数据将解析为我的对象。

我的UITableViewController还有一个带有选择器方法的NSNotification Observer。如果模型类发布通知,则会触发此选择器方法(如果模型完成请求并从服务器解析数据,则发布通知)。

选择器方法将在调度主队列块中执行“self.tableView.reloadData()”。

调试器显示对象不是nil但tableView为空。我不知道为什么tableview是空的。

来自我的UITableViewController的部件:

import UIKit

class 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
    }
}

调试器截图:

enter image description here

增加: 如果我尝试使用静态单元格初始化tableView,它将显示静态单元格。但是在viewDidLoad中实例化之后,当触发通知时,tableview为空。如果我像空盘或轻击手势那样与空tableView交互,我将收到错误:appdelegate(thread1)中的EXC_bad_Access

1 个答案:

答案 0 :(得分:0)

我没有发现mvc通信的Notification-pattern问题,但我认为这是线程的问题。解决方案是我切换到kvc模式,现在我的tableView不再是空的。