我试图使用RealmSwift
以便将项目保存到Swift 4的手机存储中。一个用于保存功能,另一个用于将所有保存的项目显示到TableView中。我有一个可编译的编码形式,但是我在调用Thread 1: signal SIGABRT
时在行上抛出了错误realm.add
。当我看到要保存的视图时,我正在使用带有按钮的IBAction来启动保存功能。谁能帮我解决这个问题?我认为问题是当我设置领域变量时,但是我不确定。
更新:
我已更改实现,以反映此主题中有关我的原始问题的想法。这样做之后,在将项目添加到领域的调用被称为i API源代码内的EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
崩溃。具体来说,我在API的此功能时崩溃了
//CODE EXCERPT FROM REALMSWIFT API
// Property value from an instance of this object type
id value;
if ([obj isKindOfClass:_info.rlmObjectSchema.objectClass] &&
prop.swiftIvar) {
if (prop.array) {
return static_cast<RLMListBase *>(object_getIvar(obj,
prop.swiftIvar))._rlmArray;
}
else { // optional
value = static_cast<RLMOptionalBase *>(object_getIvar(obj,
prop.swiftIvar)).underlyingValue; //CRASH OCCURS HERE!!!!!!!!
}
}
else {
// Property value from some object that's KVC-compatible
value = RLMValidatedValueForProperty(obj, [obj
respondsToSelector:prop.getterSel] ? prop.getterName : prop.name,
_info.rlmObjectSchema.className);
}
return value ?: NSNull.null;
import UIKit
import RealmSwift
class DetailsViewController: UIViewController {
var titleOfBook: String?
var author: String?
@IBAction func SavetoFavorites(_ sender: Any) {
DispatchQueue.global().async { [weak self] in
guard let strongSelf = self else { return }
guard let realm = try? Realm() else {
return
}
let newItem = Favorites()
newItem.title = strongSelf.titleOfBook
newItem.author = strongSelf.author
try? realm.write {
realm.add(newItem) // Crashes on this line
}
}
}
import UIKit
import RealmSwift
final class Favorites: Object {
var title: String?
var author: String?
}
class FavoritesTableViewController: UITableViewController {
var items: Array<Favorites> = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier:
"cell")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 0
}
override func tableView(_ tableView: UITableView?,
numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
let item = items[indexPath.row]
cell.textLabel?.text = item.title
cell.detailTextLabel?.text = item.author
return cell
}
var selectedIndexPath: NSIndexPath = NSIndexPath()
override func tableView(_ tableView: UITableView, willSelectRowAt
indexPath: IndexPath) -> IndexPath? {
selectedIndexPath = indexPath as NSIndexPath
return indexPath
}
最佳答案
您必须将realm.add(newItem)
包装在事务中:
try! realm.write {
realm.add(newItem)
}
请注意,写事务会阻塞它们所在的线程,因此,如果要写入大量数据,则应在后台线程上执行(领域也必须在该线程上实例化)。您可以这样:
@IBAction func saveToFavorites(_ sender: Any) {
DispatchQueue.global().async { [weak self] in
guard let strongSelf = self else { return }
guard let realm = try? Realm() else {
// avoid force unwrap, optionally report an error
return
}
let newItem = Favorites()
newItem.title = strongSelf.titleOfBook
newItem.author = strongSelf.author
try? realm.write {
realm.add(newItem)
}
}
}
更新:我还没有注意到您的模型也有问题-因为Realm是用Objective C编写的,所以应该使用
@objc dynamic
修饰符标记模型属性:final class Favorites: Object {
@objc dynamic var title: String?
@objc dynamic var author: String?
}