5

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 で問題なく動作しました。

4

0 に答える 0