[英]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.