У меня есть tableViewController (ArticlesV C), который отображает массив статей, полученных из API. Каждая из этих tableViewCell имеет кнопку «Дополнительные действия», которая позволяет пользователю сохранить статью для последующего чтения в SavedV C. Обратите внимание, что в Realm DB записываются только сохраненные статьи, отображение статей в статьяхV C не записывается в Realm DB.
Если пользователь сохранил статью, я бы показал «Удалить сохраненную статью» в противном случае я показываю «Сохранить на потом». Я прошу Realm провести эту проверку.
Однако, если я удалю сохраненную статью (или все сохраненные статьи) из Realm из SavedV C и go обратно в ArticlesV C и начну прокручивать tableView, произойдет сбой с указанной выше ошибкой . Эта ошибка sh происходит периодически, поэтому ее довольно сложно определить.
Код
//At ArticlesVC, where articles are fetched via API
func getArticles() {
AF.request(apiUrl).responseJSON { (response) in
//Error checks and decoding ...
self.articles = try decoder.decode(Article.self, from: data)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ArticleCell
cell.article = articles[indexPath.row]
cell.moreButton.tag = indexPath.row
cell.moreButton.addTarget(self, action: #selector(moreButtonTapped(sender:)), for: .touchUpInside)
return cell
}
@objc func moreButtonTapped(sender: UIButton) {
let buttonTag = sender.tag
let article = articles[buttonTag]
let alert = UIAlertController(title: "More", message: nil, preferredStyle: .actionSheet)
let action = getAction(article: article)
alert.addActions([action, .cancelAction()])
//present alert
}
func getAction(article: Article) -> UIAlertAction {
do {
let realm = try Realm()
let articleInRealm = realm.objects(Article.self).filter("id == %@", article.id)
if articleInRealm.isInvalidated {
return UIAlertAction(title: "Save for later", style: .default, handler: {(_) in
self.saveArticle(article: article)
})
} else {
if articleInRealm.count == 0 {
return UIAlertAction(title: "Save for later", style: .default, handler: {(_) in
self.saveArticle(article: article)
})
} else {
return UIAlertAction(title: "Remove saved article", style: .destructive, handler: {(_) in
self.deleteArticle(article: articleInRealm)
})
}
}
} catch {
Log("Err getting article: \(error.localizedDescription)")
return UIAlertAction(title: "Save for later", style: .default, handler: {(_) in
self.saveArticle(article: article)
})
}
}
func saveArticle(article: Article) {
do {
let realm = try Realm()
try realm.write {
realm.add(article, update: .modified)
}
} catch {
Log("Err saving article: \(error.localizedDescription)")
}
}
func deleteArticle(article: Results<Article>) {
do {
let realm = try Realm()
try realm.write {
realm.delete(article)
}
} catch {
Log("Err saving article: \(error.localizedDescription)")
}
}
//At SavedVC, which is another VC in the tabBarController.
//ArticlesVC is in tab1 and SavedVC is in tab2
var notificationToken: NotificationToken? = nil
var articles: Results<Article>?
override func viewDidLoad() {
super.viewDidLoad()
subscribeToRealmNotifications()
}
fileprivate func subscribeToRealmNotifications() {
let realm = try! Realm()
let results = realm.objects(Article.self)
notificationToken = results.observe { [weak self] (changes: RealmCollectionChange) in
guard let tableView = self?.tableView else { return }
switch changes {
case .initial:
self?.articles = results
tableView.reloadData()
case .update(_, _, _, _):
tableView.reloadData()
case .error(let error):
fatalError("Realm notif: \(error.localizedDescription)")
}
}
}
Я предполагаю, что из-за того, что я удалил статьи в SavedV C, но Статьи V C по-прежнему указывает на те объекты Realm, которые больше не существуют и поэтому разбились.
Я прочитал несколько сообщений SO, в которых предлагается выполнить проверку obj.isInvalidated
, что я сделал и включил условие для этого. Но это все равно вылетает.
Другие попытки включают:
- с использованием
realm.create()
вместо realm.add()