|
I am getting an out of memory error on a view I created to allow users to review a bunch of images. I am sure the issue is that the upper limit is unbounded. I am using a LazyVGrid with each card being loaded as defined in a custom SwiftUI View. As the user scrolls thru the Grid, it will eventual crash the app. The data is stored as .externalStorage in a SwiftData store. I have run it in the profiler and it is giving me low memory warnings, and as above, it will eventually crash. I am pretty sure that Views are the issue, but I am not sure how to tell Swift to unload them when they are not on the screen and reload them when they are brought back into scroll view. Has anyone seen a good tutorial or set of guidance to help me work my way thru this? Thanks Here's the detail messge from XCode when I was running it in debug mode:
|
|
See "Inspecting the debug memory graph" in: developer.apple.com/documentation/xcode/gathering-information-about-memory-use Look for a retain cycle, which would be a circular connection in the Memory Graph. |
|
Thank you @bobstern - So it appears to be that the individual card views are definitely showing a retain cycle Now this is loading up all the images for a PDF print feature, so I would assume it needs to load them, I see the same retain cycle when I was loading the page to show them all. Do I need to handle the memory myself for paging thru the LazyVGrid view? This is way outside of my comfortzone right now. It can't be as easy as changing the image to a weak reference, or does that allow the LazyVGrid to release and reacquire? |
|
It would be easier for us if you show us the code of your CardView and where it is called. Perhaps adding a As I'm not allowed to post a link to any other site and this software automatically transforms this to a link you need to type it yourself. cocoacasts dot com/what-is-the-difference-between-weak-and-unowned-references-in-swift |
|
There's a bit of layering here.. I have a FilteredList that lets you pick the type of LazyVGrid you'd like:
If we look at one of these (ViewCardsView) we see the following (this is including the PDF Print function, which is causing things to load twice when I load the view. I can't take it off of @MainActor for the renderer, but I am not sure how I can make that only happen when the user choose the shareSheet):
ScreenView and PrintView are different layouts for the same Cards:
Which ultimately loads an individual card via MenuOverlayView:
I hope this helps... |
|
You haven’t revealed your definitions of the Did you really write all this code before testing it? You may have to create a new Xcode project with only the lowest level view, test that, and then add more of your complexity a little at a time, testing after each addition. In addition to the Apple article referenced above, see the tutorial on Instruments (not updated since 2018, unfortunately): help.apple.com/instruments/mac/10.0/#/dev022f987b p.s. for |
|
|
|
Thanks @bobstern - I have made my repo available publically on github - https://github.com/TheApApp/CardTrackerSwiftData - as this is more of a personal project. A Card is an instance of a GreetingCard sent to a specific Recipient
While a Greeting Card is a card
Think about it this way, you may buy a bunch of "thank you" greeting cards, and then you send 1 card to someone. The project worked fine for years until I really started loading up the number of cards in the application. I first found an issue with my compression not working. But the print function is something I very recently added. I think another issue is I should build out my unit tests. (sorry to take so long to respond - as this is just a nights/weekends project). I really do appreciate any pointers and will go back thru the instruments class from 2018. |
|
So I ran instruments and had it crash out of the app, but Leaks can't be causing it now.. as this is what I am seeing 112 bytes is not much of leak. But my heap allocation is going thru the roof, which I am sure is the issue with loading up all the images in the Greeting Card Picker. Is it possible that SwiftUI and SwiftData are not releasing memory when I am switching between tabs? |
|
When debugging "Out of Memory" errors, start by identifying potential memory leaks or inefficient memory usage in your code. Utilize tools like memory profilers and heap analyzers to pinpoint memory-hungry areas. Consider optimizing data structures, freeing unused memory, and minimizing memory allocations. Additionally, ensure proper resource management, handle exceptions gracefully, and consider scaling resources if necessary. |
|
In the
Beyond that, I’m out of my depth. I suggest you repost your question with SwiftData in the title so that SwiftData experts will see it. To facilitate help from others, I suggest you rename the |
|
Another idea: The heap, where you have exploding memory, contains the results of all your queries. If you don’t get more focussed advice from a SwiftData expert, you might try a trial-and-error approach of commenting-out all of your queries and assiging each of their vars to a constant value, then one-by-one reinstaing the queries until the heap size explodes again. |
|
Thanks @Bobstern, It has been a crasy week (I only get to work on this in my spare time), so I will take your advice to heart. The original version of this app I wrote in CoreData, but was much more limited, so I took a lot of liberties when I rewrote it for SwiftData, and I am just learning to understand SwiftData. |
|
I expect it would be easier for you to stick with Core Data because the model editor defines relationships clearly and unambiguously, as opposed to wondering what SwiftData will infer from your model definition. I'd love to learn from someone who understands both Core Data and SwiftData what the advantage would be of switching to SwiftData in your situation. |
|
One of the values of SwiftData is automatic support of CloudKit, it is also why I have to make cards an Optional. I think I am going to close this thread and try and open up a new one related to SwiftData. I really want to make that work, as I want to learn SwiftData. I did pickup Paul's book, but it didn't really cover this level of details yet. |
GO FURTHER, FASTER Unleash your full potential as a Swift developer with the all-new Swift Career Accelerator: the most comprehensive, career-transforming learning resource ever created for iOS development. Whether you’re just starting out, looking to land your first job, or aiming to become a lead developer, this program offers everything you need to level up – from mastering Swift’s latest features to conquering interview questions and building robust portfolios.
You need to create an account or log in to reply.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.