我试图使用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?
}

07-24 09:44
查看更多