如何从Swift中的另一个类访问和刷新UITableView

我有一个标签栏应用程序和其视图控制器由UITableView类控制的选项卡。 我有一个类用于从服务器下载数据,然后将其保存到NSDefaults。 从那里我希望类能够更新表视图,但不知道如何访问表视图的类来更新它。

class updates { func checkForUpdates() { //start on background thread dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] in //start contacting database: UIApplication.sharedApplication().networkActivityIndicatorVisible = true let actualVersion = self.contactForUpdates() UIApplication.sharedApplication().networkActivityIndicatorVisible = false if actualVersion > self.defaults.objectForKey("version") as! Int { //update data if self.downloadUpdates() { //update version number self.defaults.setObject(actualVersion, forKey: "version") //Indicates progress finished //self.stopSpinner() } }//end updates else { //Indicates progress finished //self.stopSpinner() } }//end background queue } } 

有两个地方评论//Indicates progress finished ,我想从类中运行tableView:

 class connectTableVC: UITableViewController { ... } 

我认为最简单的做法是使用委托。

 protocol UpdateDelegate { func didUpdate(sender: Updates) } 

因此,在您的更新类中,要刷新表视图的位置,您可以调用委托didUpdate函数。 (你必须在开始调用方法的更新之前设置委托。)弱关键字是重要的,如果它不在那里,那么这两个类都不会GC'd,这将导致内存泄漏。

 class Updates { weak var delegate: UpdateDelegate? ... //Indicates progress finished self.delegate.didUpdate(self) 

在你的tableView类中,你可以通过将UpdateDelegate添加到类的顶部来订阅该委托

 class ConnectTableVC: UITableViewController, UpdateDelegate { ... let updates = Updates() updates.delegate = self ... func didUpdate(sender: updates) { dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadData() } } } 

我build议不要使用NSNotificationCenter,最大的原因是任何人都可以听取通知(这可能不太可能在你的情况下,但它仍然值得注意)。

您可以使用protocolNSNotificationCenter

NSNotificationCenter示例:

在下载数据的UIViewController中,可以在完成下载数据后发布通知,并告诉其他对象有新数据:

 NSNotificationCenter.defaultCenter(). postNotificationName("newDataNotif", object: nil) 

而任何其他想听这个通知的对象都应该注册以观察(在你的情况下是UITableViewController ):

 NSNotificationCenter.defaultCenter(). addObserver(self, #selector(shouldReload), name:"newDataNotif", object: nil) 

然后在接收通知时需要实现要调用的方法:

 func shouldReload() { self.tableView.reloadData() } 

请注意,通知也可以发送types为[NSObject : AnyObject]? 例:

 NSNotificationCenter.defaultCenter(). postNotificationName("newDataNotif", object: nil, userInfo: ["data":[dataArray]]) 

观察者将如下所示:

 NSNotificationCenter.defaultCenter(). addObserver(self, #selector( shouldReload(_:)), name:"newDataNotif", object: nil) 

方法如下:

 func shouldReload(notification:NSNotification) { println(notification.userInfo) } 

最后在你的deinit你应该删除观察者:

 deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } 

有很多方法可以做到这一点。 最标准的方法是使用委托。 委托是iOS中非常常见的模式,您正在使用它与UITableViewDataSource。 您的视图控制器是UITableView的委托,意味着它符合UITableViewDataSource协议。 所以你应该做的是为你的Updates类创build一个协议,像这样:

 protocol UpdatesDelegate { func didFinishUpdates(finished: Bool) } 

您的Updates类将具有符合此协议的委托属性:

 class Updates { var delegate: UpdatesDelegate? 

然后你把这行代表//indicates progress finished评论是:

 self.delegate?.didFinishUpdates(finished: true) 

您的ConnectTableViewController将符合协议,并从那里重新加载表视图:

 extension ConnectTableViewController: UpdatesDelegate { func didFinishUpdates(finished: Bool) { guard finished else { // Handle the unfinished state return } self.tableView.reloadData() } } 

在创buildUpdates类的实例的时候,一定要把delegate属性设置为你的ConnectTableViewController

PS您的课程需要以大写字母开头。 我已经编辑你的问题来反映这一点。

对于Swift 3

 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "newDataNotificationForItemEdit"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.shouldReload), name: NSNotification.Name(rawValue: "newDataNotificationForItemEdit"), object: nil) func shouldReload() { self.tableView.reloadData() }