Reputation: 2853
Note: I apologize if there are similar questions, but they are more specific like "UIMapView Kit Memory Leak issues", I am more concerned and really want to know in General Swift and ARC and the memory Management Issues with it.
I have done a couple of apps now in Xcode, however it was all done in Objective-C.
The memory management of UIKit objects(including UIViews and UIViewControllers) and any other object for that matter was easy to handle in Objective-C, and by easy I mean getting used to it after battling with it at some point in the Learning curve.
Now I am working with Swift trying to keep up with the "Cutting-Edge" technology. however I have noticed a slight issue with what I was able to pin down and control in Objective-C, Memory Management.
Swift comes in saying how easy is going to be for us to focus more on Code Development and not on memory management like its predecessor or soon-to-be predecessor. However I have not yet found this benefit. I have been having a horrible time with memory management of my new app. Just creating a simple UIViewController with a few views can stack up memory that I don't longer need, few Mb's at a time.
keep in mind, I have been using deconstructor(Deinit in Swift), been assigning nil to values I no longer need to use, removing SubViews from Super Views manually thinking this was the problem, even using AutoReleasePool code segment.
autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking
//But AutoReleasePool helps with this, supposedly.
}
Now the Question: Anyone here would know exactly what is the problem? Is it me doing something terrible with my code? or is there really a bug in Xcode and swift memory management? Have anyone else had this issue, have you solved it?
Here is a link explaining a bit this situation. Problems of ARC in Swift? ARC in Swift Apple Docs
Update:
You are right, I should post more about my situation: so here it goes.
I have memory starting at ~5mb as as soon as the app starts.
Once I start navigating around the app. I notice how memory starts to pile up little by little. but the biggest spike of memory start to pile up when I use UIMapView of about 25+ Mbs.
when using just a regular UITableViewController it just piles up ~2mbs every time I push(to NavController) the same UITableViewController. When I tab that TableViewCell it opens another ViewController with a UIMapView, this is where the memory starts to pile up really good.
Rememeber I am just going back and forth navigating through the app. Just a total of 4 UIViewControllers including My Menu.
But here is the thing... All these memory SnapShots you see are after I stop navigating and go back to the main menu, the Root ViewController of my Navigation Controller.
Upvotes: 1
Views: 1118
Reputation: 299683
Swift uses ARC in exactly the same way that ObjC does. If you're seeing a leak, you're probably creating a retain loop somewhere, and you would avoid those in almost exactly the same way as in ObjC (with the additional option of using unowned, but those are very similar to unsafe_unretained, so even that isn't a major change). If you're familiar with memory management in Cocoa, then you understand memory management in Swift. But we can't help based on the information you've given here (which mostly seems just commentary on Cocoa).
autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking
//But AutoReleasePool helps with this, supposedly.
}
All that said, this comment hints at your mistake. The autorelease pool needs to go inside a loop where you are rapdly creating and destroying objects, not around it. Autoreleased objects are not released until the end of the pool block, or the end of the event loop. The latter is generally sufficient, but if you're generating and releasing lots of objects, then you sometimes have to drain the pool sooner. Autorelease pools are explained in the Advanced Memory Management Programming Guide. That said, they are not commonly needed for UIKit objects.
As a side note, the "Problems of ARC in Swift?" link you give seems to be unaware of the history of Garbage Collection in Cocoa. GC was tried by Apple on Mac and rejected by Cocoa devs. Apple deprecated GC and has subsequently removed it (I was at WWDC when they announced it was being deprecated; we applauded). It is even less applicable to iOS. An excellent discussion of this issue is in Why mobile web apps are slow. I'm not saying that GC is a bad thing. I'm saying that Apple is well aware of it, and actively chose not to incorporate it. They didn't just miss an opportunity.
EDIT: Your updated info looks like a pretty standard retain loop. I'd start with heap shot analysis to figure out what kinds of objects are involved. Make sure you're following the rules. And go from there, mostly with Instruments (especially the Allocations and Leaks instruments). One key is that view controllers should generally not retain other view controllers at all. They should talk to each other through the model. You must be careful using self
in blocks. The normal rules. They're the same in ObjC and in Swift. But heap shot is definitely the place to start. Find out what is leaking; then figure out why.
Upvotes: 3