mmehr2 / StampCollection

My iOS code for managing my stamp collection.
0 stars 0 forks source link

Export Backup strategies (CSV and/or CSV+Email) are broken #5

Closed mmehr2 closed 2 months ago

mmehr2 commented 2 months ago

When we execute one of the Export options on the main item collection view to perform backup, all the functionality proceeds but the final cleanup throws a EXC_BAD_ACCESS deep in the Dispatch code of NSManagedObjectContext.

This article suggested a promising line of research: https://stackoverflow.com/questions/75525980/thread-1-exc-bad-access-code-1-address-0x10-swiftui-main-app A comment about rewriting ManagedObjectContext code using async/await methods led to questioning the basis of my design.

My design uses async code based on GCD (Grand Central Dispatch), the core of which is seen in my CollectionStore.swift design. This was based on Marcus Zarra's 2015 article about async use of Core Data here: http://martiancraft.com/blog/2015/03/core-data-stack/

One solution would be to rewrite that code to eliminate GCD.

It seems that Swift 5.5 @ WWDC 2021 introduced a new way of doing async code (async/await). I found a couple articles, treating it as the answer to all the GCD cruftiness that made manual management of contexts a requirement, and lots of nested completion handlers. It seems that it's only available with iOS15+, so we would need to assure a minimum version for that, or keep both implementations with ifdef's. Article on new architecture: https://www.biteinteractive.com/swift-5-5-replacing-gcd-with-async-await/ Followup article with more concepts: https://www.biteinteractive.com/swift-5-5-asynchronous-looping-with-async-await/

mmehr2 commented 2 months ago

On the rewrite, Xcode says "NSManagedObject" occurs 65 times in 26 files.

So the rewrite seems to need rewritten methods in CollectionStore.swift and the 8 method patterns in the +Ex objects.

mmehr2 commented 2 months ago

The ultimate solution here was a very simple fix, just checked in. I had provided a workaround for an early bug I discovered in Swift's use of NSManagedObjectContext, and it turns out it is no longer necessary to do that. I was converting the results of a CoreData fetch() into an NSArray and looping through it. This was crashing somewhere in the loop possibly due to the inventory size now (over 10k objects now). Once I just used the results of the fetch() directly, it worked fine again.