TableView 在 executeFetchRequest 后不重新加载
TableView not reloading after executeFetchRequest
当应用程序启动时,我向我的 ViewController
发送一个执行 refreshCategories
函数的通知,问题是 tableView 仅在我滚动或长时间(20 秒或更长时间)后才重新加载。
这是我的代码:
class PopularCategoriesTableViewController: UITableViewController {
var categoryList:[Category]!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("refreshCategories"),
name: Constants.NotificationKeys.shouldReloadCategories, object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: -
func refreshCategories() {
categoryList = DataModelUtil.sharedInstance.getRecordsFromEntity(Category.classString()) as! [Category]
self.tableView.reloadData()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.01
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if categoryList == nil {
return 0
}
return categoryList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item = categoryList[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.textLabel?.text = item.name
return cell
}
}
这是执行提取的方法:
func getRecordsFromEntity(entity:String) -> [NSManagedObject]! {
let fetchRequest = NSFetchRequest(entityName: entity)
do {
return try appDelegate.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
} catch let error as NSError {
print("Could not execute FetchRequest \(error), \(error.userInfo)")
}
return nil
}
注意: 我发现使用 dispatch_async
时效果很好。
dispatch_async(dispatch_get_main_queue(),{ ()->() in
self.tableView.reloadData()
})
但我在 iOS 8 和 objective-c 中不需要这个,而且我认为每次我想重新加载数据时都使用分派是不正确的。
任何 UI 操作必须在主队列上完成。如果你不遵守这个规则,你会遇到奇怪的崩溃。我还建议您使用 NSFetchedResultsController
,因为您使用的是 table 视图。通过遵守核心数据线程规则,将您的数据保存在任何地方,您的table 将自动更新。您可以通过重置 NSFetchedResultsController 并再次初始化来在任何地方手动刷新 table。
当应用程序启动时,我向我的 ViewController
发送一个执行 refreshCategories
函数的通知,问题是 tableView 仅在我滚动或长时间(20 秒或更长时间)后才重新加载。
这是我的代码:
class PopularCategoriesTableViewController: UITableViewController {
var categoryList:[Category]!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("refreshCategories"),
name: Constants.NotificationKeys.shouldReloadCategories, object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: -
func refreshCategories() {
categoryList = DataModelUtil.sharedInstance.getRecordsFromEntity(Category.classString()) as! [Category]
self.tableView.reloadData()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.01
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if categoryList == nil {
return 0
}
return categoryList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item = categoryList[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.textLabel?.text = item.name
return cell
}
}
这是执行提取的方法:
func getRecordsFromEntity(entity:String) -> [NSManagedObject]! {
let fetchRequest = NSFetchRequest(entityName: entity)
do {
return try appDelegate.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
} catch let error as NSError {
print("Could not execute FetchRequest \(error), \(error.userInfo)")
}
return nil
}
注意: 我发现使用 dispatch_async
时效果很好。
dispatch_async(dispatch_get_main_queue(),{ ()->() in
self.tableView.reloadData()
})
但我在 iOS 8 和 objective-c 中不需要这个,而且我认为每次我想重新加载数据时都使用分派是不正确的。
任何 UI 操作必须在主队列上完成。如果你不遵守这个规则,你会遇到奇怪的崩溃。我还建议您使用 NSFetchedResultsController
,因为您使用的是 table 视图。通过遵守核心数据线程规则,将您的数据保存在任何地方,您的table 将自动更新。您可以通过重置 NSFetchedResultsController 并再次初始化来在任何地方手动刷新 table。