簡體   English   中英

iOS Swift-協議將委托發送到錯誤的TableViewController

[英]iOS Swift - Protocol sending delegate to wrong TableViewController

我有一個帶有TableViewControllers鏈的應用程序,該鏈表由通知控制器鏈接,從Web服務中檢索信息。 與上一個表中選擇的數據有關,來自下一個表的數據是從Web服務中提取的。 當我拉出任何表進行刷新時,它再次請求信息,而協議將委托消息發送到表視圖以刷新信息。

好吧,到目前為止一切都很好。 但是,我遇到了一些奇怪的事情……例如:我在tableView#2上,然后使用導航后退按鈕轉到上一張表#1。 當在#1上,我拉動tableview刷新時,它崩潰並給我一個“無法識別的選擇器發送到實例”的信息,告訴我Tableview#2沒有可選的委托方法,該方法用於獲取信息以填充TableView #1。 而且我什至不在TableView#2上,iOS正在將委托消息發送到錯誤的ViewController,因為單擊NavigationController backButton時甚至沒有關閉tableViewController……

有沒有人經歷過? 我知道這似乎有點混亂,但這是正在發生的事情。

讓我們在這里獲取一些代碼:兩個TableViewControllers:ClientsViewController和ProjectsViewController當您在ClientsViewController Table上選擇一個客戶端時,它將在ProjectsViewController Table上從該客戶端加載所有項目。

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()'從Web服務檢索所有客戶端,並使用委托'didReceiceResponseFromGetClientsRequest'重新加載表。

選擇一個客戶端后,它將選擇到下一個TableViewController,在ViewController之間傳遞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()

    }

它以與客戶端相同的方式將項目加載到屏幕上,但是現在使用委托'didReceiceResponseFromGetProjectsRequest'

現在,如果我按下導航控制器的后退按鈕,它將把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上執行此操作。

有任何想法嗎?

我嘗試了,對我有用。 2個視圖控制器,每個都有不同的數據源,兩者之間有一個“ toSecondVC”序列。

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
    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM