域在删除或写入时崩溃,libc ++ abi.dylib使应用程序崩溃:终止于未捕获的NSException类型的异常

问题描述

我在我的应用程序中添加了领域集成。过程是 1]如果list不为空,则重新加载tableview,同时调用api,以接收其响应。 2]是否根据Id检查当前值,如果存在,则从领域中删除该值,再次将值添加到领域中,并重新加载tableview。代码工作正常,如果我等待第二步完成。但是第二步是完全异步的。这是我尝试过的

当我在完成第二步之前更改viewcontroller时,发生崩溃。

public class Features : Object,Codable{
@objc dynamic var intellinectsId : String?
@objc dynamic var serviceName : String?
@objc dynamic var android_icon : String?
@objc dynamic var parentUrl : String?
@objc dynamic var url : String?
@objc dynamic var mobileOrder : String?

enum CodingKeys: String,CodingKey {

    case serviceName = "serviceName"
    case android_icon = "android_icon"
    case parentUrl = "parentUrl"
    case url = "url"
    case mobileOrder = "mobileOrder"
    case intellinectsId = "intellinectsId"
}

required convenience public init(from decoder: Decoder) throws {
    self.init()
    let values = try decoder.container(keyedBy: CodingKeys.self)
    serviceName = try values.decodeIfPresent(String.self,forKey: .serviceName)
    android_icon = try values.decodeIfPresent(String.self,forKey: .android_icon)
    parentUrl = try values.decodeIfPresent(String.self,forKey: .parentUrl)
    url = try values.decodeIfPresent(String.self,forKey: .url)
    mobileOrder = try values.decodeIfPresent(String.self,forKey: .mobileOrder)
    intellinectsId = try values.decodeIfPresent(String.self,forKey: .intellinectsId)
    
}
required init() {
   
}

}

我为RealmService创建了一个

class RealmService {

private init() {}
/// To get singleton class
static let shared = RealmService()
/// To get realm object instance
var realm = try! Realm()

/// To create a record or adding new object to database
func create<T: Object>(_ object: T) {
    do {
        try realm.safeWrite {
            //realm.add(object)
            realm.create(T.self,value: object)
            //realm.create(T.self,value: object,update: .modified)
        }
    } catch  {
        post(error)
    }
}


/// To update/modify particular record/object in the database
func update<T: Object>(_ object: T,with dictionary: [String: Any?]) {
    do {
        try realm.write {
            for (key,value) in dictionary {
                object.setValue(value,forKey: key)
            }
            realm.add(object,update: .all) //add(object,update: true)
        }
    } catch  {
        post(error)
    }
}

/// To delete/remove record or object database
func delete<T: Object>(_ object: T) {
    do {
        try realm.write {
            realm.delete(object)
        }
    } catch  {
        post(error)
    }
}

/// To handle the errors while performing realmDB opration
func post(_ error: Error) {
    NotificationCenter.default.post(name: NSNotification.Name("RealmError"),object: error)
}

/// To observe realm error in the particular View controller
func observeErrors(in vc: UIViewController,completionHandler: @escaping(Error?) -> Void) {
    NotificationCenter.default.addobserver(forName: NSNotification.Name("RealmError"),object: nil,queue: nil) { (notification) in
        completionHandler(notification.object as? Error)
    }
}

/// To stop observing errors in particular View Controller
func stopObservingErrors(in vc: UIViewController) {
    NotificationCenter.default.removeObserver(vc,name: NSNotification.Name("RealmError"),object: nil)
}

/// To delete complete realm form the app
func completeDeleteRealm() {
    let realmURL = Realm.Configuration.defaultConfiguration.fileURL!
    let realmURLs = [
        realmURL,realmURL.appendingPathExtension("lock"),realmURL.appendingPathExtension("note"),realmURL.appendingPathExtension("management")
    ]
    for URL in realmURLs {
        do {
            try FileManager.default.removeItem(at: URL)
        } catch {
            post(error)
        }
    }
}

}

现在在View控制器中,我正在像这样从id的领域获取

var dashboardList : Results<Features>{
    get{
        return RealmService.shared.realm.objects(Features.self).filter(nspredicate(format: "intellinectsId == %@",HelperFunctions().getUserInfoFromDefaults()?.intellinectsId ?? ""))
    }
}

..如步骤1所示,如果dashboardList计数> 0,则重新加载tableview,同时,调用和api来获取详细信息,然后再次执行第二步,如下所示:

if let responseList = response.array,responseList.count > 0{
               
                //remove existing data from realm
                let removeHMC = RealmService.shared.realm.objects(Features.self).filter(nspredicate(format: "intellinectsId == %@",intellinectsId))
                if let realm = try? Realm(){
                    try? realm.write {
                        realm.delete(removeHMC)
                    }
                }
                if let featuresList = responseList[0]["features"].array,featuresList.count > 0{
                    for val in featuresList{
                        let feature = Features()
                        feature.intellinectsId = intellinectsId
                        feature.serviceName = val["serviceName"].string
                        feature.android_icon = val["android_icon"].string
                        feature.parentUrl = val["parentUrl"].string
                        feature.url = val["url"].string
                        feature.mobileOrder = val["mobileOrder"].string
                        RealmService.shared.create(feature)
                    }
                }
            }

如果我等待完成,那么它将正常工作。但是,如果我继续下一个vc。我收到类似

错误
libc++abi.dylib: terminating with uncaught exception of type NSException

查看特定问题后,我收到了错误消息

Terminating app due to uncaught exception 'RLMException',reason: 'Object has been deleted or invalidated.'

我也应用了this技巧。但是从领域删除值之后,再次向表视图显示会导致此问题。我不知道。请帮助

解决方法

在响应中,当您删除以前的功能列表时,您正在创建Realm()的新实例,这将导致这两者之间的不一致。 尝试删除它并使用相同的RealmService.shared

    //remove existing data from realm
let removeHMC = RealmService.shared.realm.objects(Features.self).filter(NSPredicate(format: "intellinectsId == %@",intellinectsId))
RealmService.shared.delete(removeHMC)