有时刷新的作品有时候不会
我有let blurEffect = UIBlurEffect(style: .Light)
let visualEffect = UIVisualEffectView(effect: blurEffect)
visualEffect.frame = cell.attachedImage.bounds
cell.attachedImage.addSubview(visualEffect)
基本上是新闻Feed。我还实现了一个pull to refresh功能。但是有时候当我拉动刷新它会给我错误
'数组索引超出范围'。
我知道这意味着它试图得到的物品不存在,但你能告诉我为什么吗?这是我的代码:
UITableViewController
和refresh()函数:
override func viewDidLoad() {
super.viewDidLoad()
refresher = UIRefreshControl()
refresher.attributedTitle = NSAttributedString(string: "Pull to refresh")
refresher.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refresher)
refresh()
tableView.delegate = self
tableView.dataSource = self
}
和
func refresh() {
//disable app while it does stuff
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
//get username and match with userId
let getUser = PFUser.query()
getUser?.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let users = objects {
//clean arrays and dictionaries so we dont get indexing error???
self.messages.removeAll(keepCapacity: true)
self.users.removeAll(keepCapacity: true)
self.usernames.removeAll(keepCapacity: true)
for object in users {
if let user = object as? PFUser {
//make userId = username
self.users[user.objectId!] = user.username!
}
}
}
})
let getPost = PFQuery(className: "Posts")
getPost.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if error == nil {
if let objects = objects {
self.messages.removeAll(keepCapacity: true)
self.usernames.removeAll(keepCapacity: true)
for object in objects {
self.messages.append(object["message"] as! String)
self.usernames.append(self.users[object["userId"] as! String]!)
self.tableView.reloadData()
}
}
}
}
self.refresher.endRefreshing()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
}
答案 0 :(得分:1)
如果您正在执行两项后台任务,则会遇到竞争条件,其中第二项任务取决于从第一项返回的值。 getUser?.findObjectsInBackgroundWithBlock
将立即返回,getPost.findObjectsInBackgroundWithBlock
将开始执行。 getPost应位于getUser的块内,以确保序列正确。
同样,以下两行应位于第二个块内:
self.refresher.endRefreshing()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
给定错误行,您可能还会在两个后台任务之间出现争用条件并显示tableView。我倾向于尝试:
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) {
return self.refresher.refreshing ? 0 : self.usernames.count
}
这样,在后台刷新完成之前,您不会触摸self.usernames
(只要您记得将endRefreshing
放在第二个块中,该块也放在第一个块内。 / p>
答案 1 :(得分:0)
我相信在self.users[user.objectId!] = user.username!
中,user.ObjectId是由parse分配的一些随机值,如下所示:" 34xcf4"。这就是您可能获得'Array index out of range'
。
答案 2 :(得分:0)
配置UITableView有两个必需的方法:
tableView(_:cellForRowAtIndexPath:)
和tableView(_:numberOfRowsInSection:)
在您的代码中,您只提供一个必需的方法,如果您没有实施第二种方法,那么可能会导致错误。
答案 3 :(得分:0)
您在对阵列的每次添加时调用self.tableView.reloadData(),并在后台线程中执行此操作。
作为一般规则,您不应在后台线程中进行UI更新。当你清除self.messages和self.usernames时,因为你在后台线程中,没有什么能阻止tableview尝试在索引中获取一个不再包含数组中任何数据的单元格。
如果你想将你的代码保存在后台线程中(尽管可能存在风险),你至少应该在重新加载数组之前调用.beginUpdates并等到它们全部完成后再调用reload和endUpdates。