iOS Swift - 将委托发送到错误的TableViewController的协议

时间:2015-03-06 10:45:24

标签: ios swift delegates protocols

我有一个带有TableViewControllers链的应用程序,它由通知控制器链接,从Web服务中检索信息。下一个表中的数据是从Web服务中提取的,关于在前一个服务器上选择的数据。当我拉动任何表进行刷新时,它再次请求协议将信息发送给tableview以刷新信息的信息。

好吧,到目前为止一切顺利。但是,我遇到了一些奇怪的事情......例如:我在tableView#2上,然后使用导航后退按钮进入上一个表#1。当在#1上,我拉出tableview进行刷新时,它会崩溃并给我一个"无法识别的选择器发送到实例"告诉Tableview#2没有可选的委托方法,用于获取填充TableView#1的信息。我甚至不再使用TableView#2,iOS正在将委托消息发送到错误的ViewController,因为当单击NavigationController backButton时,tableViewController甚至不被解雇...

有没有人经历过?我知道它似乎有点混乱,但它正是发生的事情。

让我们在这里获得一些代码: 两个TableViewControllers:ClientsViewController和ProjectsViewController 当您在ClientsViewController表上选择客户端时,它会在ProjectsViewController表上从客户端加载所有项目。

ClientsViewController

override func viewDidLoad() {
        super.viewDidLoad()
        wsCommHandler.delegate = self
        self.tableView.delegate = self
        self.tableView.dataSource = self

        self.refreshControl!.addTarget(self, action: Selector("refreshClients:"), forControlEvents: UIControlEvents.ValueChanged)
        wsCommHandler.getClients()

    }

    func refreshClients(sender:AnyObject){
        println("Refreshing")
        self.refreshControl?.beginRefreshing()
        wsCommHandler.getClients()
        self.refreshControl?.endRefreshing()
    }

func didReceiceResponseFromGetClientsRequest(response: [AnyObject]) {
        self.clients = response
        self.tableView.reloadData()

    }

wsCommHandler' getClients()'从webservice中检索所有客户端并使用委托&did; didReceiceResponseFromGetClientsRequest'重新加载表格。

当选择客户端时,它会转到下一个TableViewController,在ViewControllers之间传递client_id。

这是来自ProjectsViewController

的代码示例
override func viewDidLoad() {
        super.viewDidLoad()
        wsCommHandler.delegate = self
        self.tableView.delegate = self
        self.tableView.dataSource = self

        self.refreshControl!.addTarget(self, action: Selector("refreshProjects:"), forControlEvents: UIControlEvents.ValueChanged)
        wsCommHandler.getProjectsByClient(client_id) 
    }

    func refreshProjects(sender:AnyObject){
        println("Refreshing")
        self.refreshControl?.beginRefreshing()
        wsCommHandler.getProjectsByClient(client_id)
        self.refreshControl?.endRefreshing()
    }

    func didReceiceResponseFromGetProjectsRequest(response: [AnyObject]) {
        self.projects = response
        self.tableView.reloadData()

    }

它以与客户端相同的方式加载屏幕上的项目,但是现在使用委托&did ;;来自ReceiceResponseFromGetProjectsRequest'

现在,如果我按下导航控制器后退按钮,它会将ClientsViewController返回到前面(不重新加载)...当我拉它以刷新时。调用该类,检索数据然后:崩溃!

2015-03-06 09:26:18.978 PostItHours [9174:792018] - [PostItHours.ProjectsViewController didReceiceResponseFromGetClientsRequest:]:无法识别的选择器发送到实例0x7fe0c4132c30 2015-03-06 09:26:18.980 PostItHours [9174:792018]由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' - [PostItHours.ProjectsViewController didReceiceResponseFromGetClientsRequest:]:无法识别的选择器发送到实例0x7fe0c4132c30'

正如大家们所看到的那样,它正试图在backButton已经解散的ProjectsViewController上做到这一点。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我试过,它对我有用。 2个viewcontrollers,每个都有不同的数据源,两者之间有一个“toSecondVC”segue。

ViewController:

import UIKit

class ViewController: UITableViewController {
    var texts = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        texts.append("viewController")
        self.title = "viewController"
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        refreshControl = UIRefreshControl()
        refreshControl!.addTarget(self,
            action: "handleRefresh:",
            forControlEvents: .ValueChanged)

        tableView.addSubview(refreshControl!)

    }

    func handleRefresh(paramSender: AnyObject){
        //pause it 1 sec
        let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC))
        dispatch_after(popTime,
            dispatch_get_main_queue(), {
                self.texts.append(String("viewController-\(self.texts.count+1)"))
                self.refreshControl!.endRefreshing()
                let indexPathOfNewRow = NSIndexPath(forRow: self.texts.count - 1,
                    inSection: 0)

                self.tableView!.insertRowsAtIndexPaths([indexPathOfNewRow],
                    withRowAnimation: .Automatic)
        })
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "toSecondVC" {
            let viewController:SecondVC = segue.destinationViewController as SecondVC
            let indexPath = self.tableView.indexPathForSelectedRow()
            viewController.stringSelected = texts[indexPath!.row]
        }
    }

    //MARK : TableView Delegate
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        cell.textLabel.text = texts[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return texts.count
    }
}

第二个VC:

import UIKit

class SecondVC: UITableViewController {
    var texts = [String]()
    var stringSelected = String()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "secondVC"
        texts.append("secondVC")
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        refreshControl = UIRefreshControl()
        refreshControl!.addTarget(self,
            action: "handleRefresh:",
            forControlEvents: .ValueChanged)

        tableView.addSubview(refreshControl!)

        println("stringSelected : \(stringSelected)")
    }

    func handleRefresh(paramSender: AnyObject){

        //pause it 1 sec
        let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC))
        dispatch_after(popTime,
            dispatch_get_main_queue(), {
                self.texts.append(String("secondVC-\(self.texts.count+1)"))
                self.refreshControl!.endRefreshing()
                let indexPathOfNewRow = NSIndexPath(forRow: self.texts.count - 1,
                    inSection: 0)

                self.tableView!.insertRowsAtIndexPaths([indexPathOfNewRow],
                    withRowAnimation: .Automatic)

        })

    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        cell.textLabel.text = texts[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return texts.count
    }


}