Ensembles フレームワークを使用してデータを iCloud と同期しています。Swift 3 に移行するまで、すべてが正常に機能していました。
フレームワークは Objective-C にあり、appDelegate
関数は Swift 3 に移行しました。それ以来、私は問題を抱えていました。appDelegate.syncWithCompletion
への変更を保存するときに、アプリ全体でを呼び出しますNSManagedObjects
。
ここにappDelegate
関数があります
// MARK: Ensembles
var cloudFileSystem: CDECloudFileSystem!
var ensemble: CDEPersistentStoreEnsemble!
func syncWithCompletion(completion:@escaping (_ completed:Bool) -> Void) {
if !ensemble.isLeeched {
ensemble.leechPersistentStore { error in
if error != nil {
print("cannot leech \(error!.localizedDescription)")
completion(false)
}
else {
print("leached!!")
completion(true)
}
}
}
else {
ensemble.merge{ error in
if error != nil {
print("cannot merge \(error!.localizedDescription)")
completion(false)
}
else {
print("merged!!")
completion(true)
//NSNotificationCenter.defaultCenter().postNotificationName("Updated-DB", object: nil)
}
}
}
}
func persistentStoreEnsemble(_ ensemble: CDEPersistentStoreEnsemble, didSaveMergeChangesWith notification: Notification) {
managedObjectContext.performAndWait {
print("Database was updated from iCloud")
self.managedObjectContext.mergeChanges(fromContextDidSave: notification as Notification)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Updated-DB"), object: nil)
}
}
private func persistentStoreEnsemble(ensemble: CDEPersistentStoreEnsemble!, globalIdentifiersForManagedObjects objects: [AnyObject]!) -> [AnyObject]! {
return (objects as NSArray).value(forKeyPath: "uniqueIdentifier") as! [AnyObject]
}
iCloud ドライブをオフにすると、アプリの実行時に次のエラーが表示されます。CPU は 100% を超えており、メモリとエネルギーも高いです。
デバッガーからのメッセージ: メモリの問題により終了しました
データの同期とマージのためにiCloudドライブがオンになっていると、次のようになります
Objective-C クラス情報を読み込めませんでした。これにより、利用可能な型情報の品質が大幅に低下します。
さらにインストゥルメントを調査すると、Ensembles フレームワークの次の関数に移動します。dispatch_async(queue,^{
ラインをより具体的に。
#pragma mark Merging Store Modification Events
- (void)mergeEventsWithCompletion:(CDECompletionBlock)completion
{
NSAssert([NSThread isMainThread], @"mergeEvents... called off main thread");
newEventUniqueId = nil;
// Setup a context for accessing the main store
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
NSPersistentStore *persistentStore = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:self.persistentStoreOptions error:&error];
if (!persistentStore) {
[self failWithCompletion:completion error:error];
return;
}
self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.managedObjectContext performBlockAndWait:^{
self.managedObjectContext.persistentStoreCoordinator = coordinator;
self.managedObjectContext.undoManager = nil;
}];
NSManagedObjectContext *eventStoreContext = self.eventStore.managedObjectContext;
// Integrate on background queue
dispatch_async(queue,^{
@try {
__block NSError *error;
// Apply changes
BOOL integrationSucceeded = [self integrate:&error];
if (!integrationSucceeded) {
[self failWithCompletion:completion error:error];
return;
}
// If no changes, complete
__block BOOL hasChanges;
[managedObjectContext performBlockAndWait:^{
hasChanges = managedObjectContext.hasChanges;
}];
if (!hasChanges) {
[self completeSuccessfullyWithCompletion:completion];
return;
}
// Create id of new event
// Register event in case of crashes
newEventUniqueId = [[NSProcessInfo processInfo] globallyUniqueString];
[self.eventStore registerIncompleteEventIdentifier:newEventUniqueId isMandatory:NO];
// Create a merge event
CDEEventBuilder *eventBuilder = [[CDEEventBuilder alloc] initWithEventStore:self.eventStore];
eventBuilder.ensemble = self.ensemble;
CDERevision *revision = [eventBuilder makeNewEventOfType:CDEStoreModificationEventTypeMerge uniqueIdentifier:newEventUniqueId];
// Repair inconsistencies caused by integration
BOOL repairSucceeded = [self repairWithMergeEventBuilder:eventBuilder error:&error];
if (!repairSucceeded) {
[self failWithCompletion:completion error:error];
return;
}
// Commit (save) the changes
BOOL commitSucceeded = [self commitWithMergeEventBuilder:eventBuilder error:&error];
if (!commitSucceeded) {
[self failWithCompletion:completion error:error];
return;
}
// Save changes event context
__block BOOL eventSaveSucceeded = NO;
[eventStoreContext performBlockAndWait:^{
BOOL isUnique = [self checkUniquenessOfEventWithRevision:revision];
if (isUnique) {
[eventBuilder finalizeNewEvent];
eventSaveSucceeded = [eventStoreContext save:&error];
}
else {
error = [NSError errorWithDomain:CDEErrorDomain code:CDEErrorCodeSaveOccurredDuringMerge userInfo:nil];
}
[eventStoreContext reset];
}];
if (!eventSaveSucceeded) {
[self failWithCompletion:completion error:error];
return;
}
// Notify of save
[self.managedObjectContext performBlockAndWait:^{
if (didSaveBlock) didSaveBlock(managedObjectContext, saveInfoDictionary);
}];
saveInfoDictionary = nil;
// Complete
[self completeSuccessfullyWithCompletion:completion];
}
@catch (NSException *exception) {
NSDictionary *info = @{NSLocalizedFailureReasonErrorKey:exception.reason};
NSError *error = [NSError errorWithDomain:CDEErrorDomain code:CDEErrorCodeUnknown userInfo:info];
[self failWithCompletion:completion error:error];
}
});
}
エラーの原因とその解決方法を知っている人はいますか? コードをループし続けているようで、NSManagedObjects も複製され続けています。
PS: このプロジェクトは、swift 2.2 で問題なく動作しました。