2015-03-06 2 views
1

У меня есть приложение с цепочкой TableViewControllers, связанное с контроллером уведомлений, получающее информацию из веб-службы. Данные из следующей таблицы извлекаются из веб-сервиса, в отношении данных, выбранных на предыдущем. Когда я вытягиваю любую таблицу для обновления, она снова запрашивает информацию, которую протокол отправляет делегатскому сообщению в tableview для обновления информации.iOS Swift - Протокол отправки делегата в неправильный TableViewController

Ну, пока все хорошо. Но, я испытываю что-то странное ... Пример: я нахожусь на tableView # 2, а затем использую кнопку навигации назад, чтобы перейти к предыдущей таблице, №1. Когда, на # 1, я вытягиваю tableview для обновления, он сбой и дает мне один из этих «нераспознанных селекторов, отправленных экземпляру», сообщая, что Tableview # 2 не имеет необязательного метода делегата, который используется для получения информации для заполнения TableView # 1. И я даже не на TableView # 2 больше, iOS отправляет сообщение делегата в неправильный ViewController, поскольку tableViewController даже не был уволен при нажатии на кнопку ClickButton NavigationController ...

Кто-нибудь испытал это? Я знаю, что это немного смущает, но это то, что происходит.

Позволяет получить код здесь: Два 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() 

    } 

'getClients()' The wsCommHandler извлекает из веб-сервиса все клиенты и использует делегат 'didReceiceResponseFromGetClientsRequest' перезагрузить таблицу.

Когда клиент выбран, он переходит к следующему TableViewController, передавая client_id между ViewControllers.

Вот пример кода из 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 обратно (без перезагрузки) ... Когда я вытаскиваю его для обновления. Класс вызывается, извлекает данные, а затем: Crash!

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»

Как вы, ребята, можете видеть, он пытается сделать это ProjectViewController, который уже был уволен, backButton.

Любые идеи?

+0

Используете ли вы UIRefreshControl? Можете ли вы показать нам какой-то код? Возможно, вы могли бы создать новый UIRefreshControl каждый раз, когда вы измените свой tableView, и соответственно измените цель refreshcontrol: 'refreshControl! .addTarget (self, ...' – Paul

+0

Paul, я обновил свой вопрос с помощью кода :) –

+0

Попробуйте переместите код 'refreshControl' в метод' viewDidAppear', который вызывается, когда представление обновляется, тогда как 'viewDidLoad' вызывается один раз и не вызывается, когда вы возвращаетесь из стека навигации, больше объяснений здесь: http://stackoverflow.com/questions/5562938/looking-to-understand-the-ios-uiviewcontroller-lifecycle – Paul

ответ

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

secondVC:

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 
    } 


} 
+0

Вы только добавляете задержку для обновления стол? Моя проблема сохраняется, даже если я вернусь к первому виду, подождите минуту, а затем попробуйте обновить его. –

+0

@LucasAlmeida. Задержка заключается в симуляции только обновления, это не связано с вашей проблемой. Я отправил код, чтобы вы могли лучше узнать, где вы, возможно, допустили ошибку. – Paul

+0

Между таблицами вы используете обычный push segue? Встроенный навигационный элемент управления? –

Смежные вопросы