Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我的领域文件不断增长,直到应用程序不再启动_Ios_Swift3_Realm - Fatal编程技术网

Ios 我的领域文件不断增长,直到应用程序不再启动

Ios 我的领域文件不断增长,直到应用程序不再启动,ios,swift3,realm,Ios,Swift3,Realm,我有一个在iOS上使用RealmSwift的应用程序,它存储了少量数据。每隔约5分钟通过CloudKit推送通知更新数据 它可以工作,除了我的领域文件不断增长,直到应用程序不再有足够的内存启动 我通过使用“writeCopy”功能在启动时压缩域,稍微解决了这个问题-如果应用程序半频繁地停止,这样就有机会运行,这通常是有效的,但是如果没有发生这种情况,并且应用程序会在几天内继续在后台更新推送通知中的数据,数据库最终将变得太大,压缩它需要很长时间,或者它只是在尝试时崩溃 我试图阅读常见问题解答中的“

我有一个在iOS上使用RealmSwift的应用程序,它存储了少量数据。每隔约5分钟通过CloudKit推送通知更新数据

它可以工作,除了我的领域文件不断增长,直到应用程序不再有足够的内存启动

我通过使用“writeCopy”功能在启动时压缩域,稍微解决了这个问题-如果应用程序半频繁地停止,这样就有机会运行,这通常是有效的,但是如果没有发生这种情况,并且应用程序会在几天内继续在后台更新推送通知中的数据,数据库最终将变得太大,压缩它需要很长时间,或者它只是在尝试时崩溃

我试图阅读常见问题解答中的“文件大小”部分,但我认为我并不完全理解导致文件大小增加的规则。它提到保持“旧领域”的开放性——这是指领域的实例,例如“let Realm=try!Realm()”还是指任何开放的对象

如果是后者,那么这很烦人,因为我在后台使用结果集上的通知来确定何时更新伴侣手表应用程序上的复杂情况

我真的很喜欢realm,我想继续使用它,但我觉得我有点不寻常的用例(长时间运行的应用程序,经常在后台更新)可能意味着我不能使用它

编辑:

“DidReceiveEmotentification”应用程序委托回调导致后台更新,如下所示:

 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    let dict = userInfo as! [String: NSObject]

    let notification = CKNotification(fromRemoteNotificationDictionary: dict)

    if notification.notificationType == .query {

        let notification = notification as! CKQueryNotification

        if let recordID = notification.recordID {

            let requestOperation = CKFetchRecordsOperation(recordIDs: [recordID])
            requestOperation.fetchRecordsCompletionBlock = { records, error in

                if let error = error {
                    os_log("Error fetching record: %@", log: Logger.default, type: .error, String(describing: error))
                } else {

                    autoreleasepool {
                        let realm = try! Realm()

                        try! realm.write {
                            records?.forEach { (key, record) in
                                switch record.recordType {
                                case "Freeway":
                                    let dict = RealmFreeway.dictionary(from: record)
                                    realm.create(RealmFreeway.self, value: dict, update: true)

                                case "Segment":
                                    let dict = RealmSegment.dictionary(from: record)
                                    realm.create(RealmSegment.self, value: dict, update: true)

                                default:
                                    os_log("Unknown record type: %@", log: Logger.default, type: .error, record.recordType)
                                }
                            }
                        }
                    }
                }
            }

            CKContainer.default().publicCloudDatabase.add(requestOperation)
        }

    }

    completionHandler(.newData)
}
手表复杂度通过RxSwift更新,如下所示:

 Observable.combineLatest(watchViewModel.freewayName.asObservable(), watchViewModel.startName.asObservable(), watchViewModel.endName.asObservable(), watchViewModel.travelTime.asObservable(), watchViewModel.color.asObservable(), watchViewModel.direction.asObservable()) {
        freewayName, startName, endName, travelTime, color, direction -> [String:Any] in

        guard let freewayName = freewayName,
            let startName = startName,
            let endName = endName,
        let direction = direction else {
                return [String:Any]()
        }

        let watchData:[String:Any] = [
            "freewayName": freewayName,
            "startName": startName,
            "endName": endName,
            "travelTime": travelTime,
            "color": color.htmlRGBColor,
            "direction": direction,
            "transfers": session.remainingComplicationUserInfoTransfers
        ]

        return watchData
    }
    .filter { $0.keys.count > 0 }
    .throttle(2.0, scheduler: MainScheduler.instance)
    .subscribe( onNext: { watchData in

        let MIN_DURATION = 24.0 * 60.0 * 60.0 / 50.0 // 50 guaranteed updates per day...
        var timeSinceLastUpdate = MIN_DURATION
        let now = Date()

        if let lastUpdated = self.lastComplicationUpdate {
            timeSinceLastUpdate = now.timeIntervalSince(lastUpdated)
        }

        // Should we use a complication update or an application context update?
        let complicationUpdate = timeSinceLastUpdate >= MIN_DURATION

        // Send the data via the appropriate method.
        if complicationUpdate {
            session.transferCurrentComplicationUserInfo(watchData)
        } else {
            try? session.updateApplicationContext(watchData)
        }

        self.lastComplicationUpdate = now
    })
    .addDisposableTo(bag)

是否在后台线程领域中打开显式自动释放池?您是否在每次更新的单个事务中进行更新?哇,这是一个非常有趣的Realm实现!你在正确的轨道上;Realm使用数据的读锁定副本来保证在给定时刻访问任何Realm数据的任何对象都不会动态更改其下的数据。因此,如果显式保留某些领域访问器(即“固定”特定版本的数据),则会导致复制数据并增加文件大小。请更新您的问题,以详细说明如何使用Realm执行此后台更新,以及如何将更改转发给Watch?如果您的所有逻辑都在主线程上,Realm会在每次运行循环迭代时自动更新版本。但是,如果你的应用程序当时被iOS支持,我不确定这是否意味着runloop当时运行正常。在这种情况下,您可以尝试在每次更新开始时对
Results
对象所属的
领域
实例调用
refresh()
。我放置了一些代码,显示推送通知的更新,以及复杂的更新代码。我认为,当应用程序处于后台时,运行循环可能不会发生。也有可能我在RxSwift上犯了严重的错误。这个应用程序对我来说是一个实验,我可以同时使用Realm+RxSwift,因为我通常不使用这两种应用程序。仔细想想——这只是我需要在保留Realm对象的RxSwift中调用“刷新”的问题吗?