drewmccormack/ensembles

CDEEEventIntegrator mergeEventsWithCompletion:_block_invoke.91 Causing App Crash

JDSX opened this issue · 24 comments

JDSX commented

My project was already up and running using Ensembles however once I migrated to Swift 3 my app now crashes. However the errors all point to the framework when debugging. I keep seeing the following error in the console when syncing;

Could not load any Objective-C class information. This will significantly reduce the quality of type information available.

or when I leave the app running I get the following memory issue

Message from debugger: Terminated due to memory issue

And when I dig further using instruments I found that the CPU over 100%, and memory and energy impact both high. When the app crashes It takes me to CDEEventIntegrator class, mergeEventsWithCompletion function and the dispatch line for `"integrate on background queue".

Im unsure how to resolve this error, and I even turned iCloud drive for the app off in settings however the app still crashes sometime after launching. I have found with iCloud ManagedObjects would keep duplicating.

Here's my Swift 3 functions in the 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]
    }

This is what I am seeing in the console

screen shot 2016-09-12 at 17 16 51

As mentioned the project was working in previous versions of Swift, but now that my functions have been migrated to Swift 3 I am getting the errors mentioned. Does anyone have any ideas why this might be happening ?

PS: I was actually running final tests before submitting my app for iOS 10 and unfortunately this issue has prevented that. Weird how I haven't had any issues until today

I am fairly sure we fixed this a couple of weeks ago. What version of the code do you have?

You should either download the latest code using the link you received when you purchased, or — if you have access to the github repo — update to the latest master branch.

Kind regards,
Drew

On 12 Sep 2016, at 19:11, Jas Singh notifications@github.com wrote:

My project was already up and running using Ensembles however once I migrated to Swift 3 my app now crashes when trying to sync with the following error;

Could not load any Objective-C class information. This will significantly reduce the quality of type information available.

Im unsure how to resolve this error, here's my functions in the 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]
}

And I see the error occurs on thread 10 when CDEEEventIntegrator mergeEventsWithCompletion:_block_invoke.91

and this is what I am seeing in the console

https://cloud.githubusercontent.com/assets/5117290/18445163/23e7d388-7914-11e6-8e9d-87ed2597fa44.png
As mentioned the project was working in previous versions of Swift, but now that my functions have been migrated to Swift 3 I am getting the errors mentioned.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub #244, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEuABjRCJef2cMJwKTXXtBdXsgANp9Qks5qpYe1gaJpZM4J60B3.

JDSX commented

Unfortunately I am using the latest release. I even updated today, removed the project app from both devices, cleared iCloud data and started fresh to see what would happen. At first neither device would sync with the error cannot merge The operation couldn’t be completed. (CDEErrorDomain error 101.) then the got runtime crashes with the error warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.

Previously when I have been able to fetch iCloud data after removing the app from the device the data would get duplicated. For each time the data would x2, I actually eded up with 26x data with 300mb taken up at one point after removing the app from the device for a few hours then re-installing.

Was hoping to update an app on the App Store for iOS 10 however am unable to with the current sync ing bugs. Am tempted to go for the CloudKit ensembles framework but unsure how quick I would be able to set up as iCloud seems to be creating to much hassle. Also

I just updated the Simple Sync example to Swift 3, and it seems to be working OK.

Maybe it is worth trying to run your project with the Zombies enabled, to see if that gives us a clue.

Ah, I just realised you are using the open source Ensembles. Is that right? There may well still be a problem there. I have only been updating Ensembles 2.

I will see if I can bring back the relevant changes to the open source project. Setting Zombies would still help to confirm this.

JDSX commented

Yes I am, oh right that makes sense. I wanted to get familiar with the open source framework, however I have just purchased Ensembles 2 because 1 has served me well for a few months, and with Swift 3 support and CloudKit the upgrade makes sense. Will try to update my project and hopefully everything will run smooth again

JDSX commented

How can I get access to the Simple Sync project in Swift 3 ? As the download files are still in swift 2.2

It’s currently only in the github repo master branch. If you send me your github username, I will give you access.

Drew

On 13 Sep 2016, at 15:37, Jas Singh notifications@github.com wrote:

How can I get access to the Simple Sync project in Swift 3 ?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub #244 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AAEuAGo9OOC5A2HNBEm3myWEH0igbeN-ks5qpqcKgaJpZM4J60B3.

JDSX commented

I just actually sent over an email but my username is JDSX, do you have any CloudKit examples in Swift yet ?

Just added you to repo.

No, we only have the Simple Sync example in Swift. The Idiomatic example (ObjC) does include CloudKit. Should only be small differences in Swift.

I still have this problem with v1.6.
Xcode8+iCloud

Can you turn on Zombies in your app and tell me where it is crashing? This info is a bit vague at the moment.

Well, I will collect more information tomorrow.

So far, I rollback to Xcode7, then the issue is gone.

Pre-condition:
1,compiled by Xcode8.
2, refresh installation
3, first time to fetch& rebase data from iCloud.

Debug Infomation:
default

**Zombie debug info:
-[NSError retain]: message sent to deallocated instance 0x174c420a0

Is that the release version (1.6)? If possible, can you pull the latest trunk from GitHub? I made a bunch more improvements to NSError handling, and I think I caught that one.

Just checked. Yes, I did change that code. See very end of this commit: bedc3f8 bedc3f8

Drew

On 14 Oct 2016, at 04:12, smallhorse1987 notifications@github.com wrote:

Pre-condition:
1,compiled by Xcode8.
2, refresh installation
3, turn app to foreground quickly right after it switch to background.

Debug Infomation:
https://cloud.githubusercontent.com/assets/18483946/19373422/5f8a79ae-91f6-11e6-8a32-92e5bb21c554.png
**Zombie debug info:
-[NSError retain]: message sent to deallocated instance 0x174c420a0


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub #244 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AAEuADsrujLpZbKlsmyPHOMc2PA-UzKJks5qzuUEgaJpZM4J60B3.

yep, 1.6.1 solve the problem. Unfortunately the version provided by CocoaPods is still the 1.6 so be sure to get the latest version from here by using in your PodFile

pod 'Ensembles', :git => 'https://github.com/drewmccormack/ensembles.git'

Sorry, somehow must have forgotten to push the update. Now done.

@drewmccormack Hello... I still have this problem with latest ensembles 😢
My podfile is configured like @mastro35

image

That doesn't look like the same problem. Not also that this thread is from 5 years ago, so unlikely.

Looking at your error, it seems that Ensembles thinks it has NSData, and it actually has an NSArray. Do you have transformable attributes? In particular, an array of values that you are transforming to data?

Thank you for quick response :)

As you said, I have transformable attributes. And the type of the array is [Date].
I don't know why this error happed 😢

What is the transformer you are using? Can you screenshot the attribute in the Core Data model?

I think I see the problem. This was changed by Apple. We have a fix for the change in Git, but it hasn't yet been released for Cocoapods yet.

I will try to release that in the coming days. For now, if you are able to use the HEAD of the Git repo, that should work.

Eg. In your pod file

pod 'Ensembles', :git => 'https://github.com/drewmccormack/ensembles.git', :commit => 'db261baa0a532408637a594055b0396fae15a91a'

Then

pod update

I applied your suggestion, but another crash is occurs.. 😢
My CoreData model has a to-many relationship, and one attribute of the entity is transformable, optional, and the type is [Date].
I also used CDEPropertyChangeValueTransformer for configure Transformer filed in my CoreData model :)

Additionally, the completion of CDEEnsemble.merge method is not called.. So CDEEventIntergrator.mergeEventsWithCompletion always works on private thread. This is identified as the cause of the increased memory usage and cpu usage of my app. Enabling ensemble uses significantly more resources than disabling it.

스크린샷 2021-08-12 오전 9 44 28

You shouldn't use CDEPropertyChangeValueTransformer. That is an internal transformer. Just use whichever transformer you were using before.

I'm not sure about the optional part. I may need to check if we handle that properly.

You may need to clear all the sync data that was created before the change. It may have the wrong values.