我有一个标签栏应用程序和一个标签,其视图控制器由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 {
...
}
答案 0 :(得分:7)
您可以使用protocol
或NSNotificationCenter
NSNotificationCenter
的示例:
从下载数据的UIViewController
,您可以在完成下载数据后发布通知,并告诉其他对象有新数据:
NSNotificationCenter.defaultCenter().
postNotificationName("newDataNotif", object: nil)
任何其他想要收听此通知的对象都应注册观察(在您的情况下为UITableViewController
):
NSNotificationCenter.defaultCenter().
addObserver(self, #selector(shouldReload),
name:"newDataNotif", object: nil)
然后你需要实现接收通知时要调用的方法:
func shouldReload() {
self.tableView.reloadData()
}
请注意,通知也可以发送类型为[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)
}
答案 1 :(得分:4)
我认为做你想做的最简单的方法就是使用委托。
protocol UpdateDelegate {
func didUpdate(sender: Updates)
}
因此,在您要更新表视图的更新类中,您将调用委托didUpdate函数。 (您必须在开始更新之前设置委托才能调用该方法。)weak关键字很重要,如果不存在,那么这两个类都不会GC,这将导致内存泄漏
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()
}
}
}
我建议不要使用NSNotificationCenter,最大的原因是任何地方的任何人都可以收听通知(在您的情况下可能不太可能,但仍然值得注意)。
答案 2 :(得分:3)
对于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()
}
答案 3 :(得分:1)
有很多方法可以做到这一点。最标准的方法是使用委托。委托是iOS中非常常见的模式,您将它与UITableViewDataSource一起使用。您的视图控制器是UITableView的委托,这意味着它符合UITableViewDataSource协议。所以你应该做的是为你的Updates
类创建一个协议,如下所示:
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()
}
}
如果您创建了Updates
类的实例,请务必将委托属性设置为ConnectTableViewController
。
P.S。您的类需要以大写字母开头。我已编辑了您的问题以反映这一点。