I`ve searched a lot about this problem but I didn´t find anything, hoping someone does it, here is my question:
Ive tested the app in the simulator a lot of times. I have ARC and all the outlets released in the viewDidUnload (Ive quite a lot of images). When I run it on the simulator, the memory continues rising again and again, when changing between views.
For example, I have a button in a view. And right clicking it, I drag it to another view, connecting them. Do I need to release anything relating in this way the views? If so, where I put the code? (I have a .h and .m for each view).I have read a lot of questions like this, but all off them referred to views related by code, not using the drag option
(Style - modal)
Please I would thank a lot any clue or help, as I have to solve this problem in a short period of time,
Thanks in advance :)
viewDidUnload is not called anymore starting with iOS6. That might explain what is happening.
Called when the controller’s view is released from memory. (Deprecated in iOS 6.0. Views are no longer purged under low-memory conditions and so this method is never called.)
Furthermore, viewDidUnload was usually called when the view was unloaded due to memory pressure, so you were anyway expected to call it from your dealloc method.
Try doing your niling in dealloc or viewDidDisappear.
You should also be aware, if you use UIImage's imageNamed to load your images, that this method will cache the images. So even when you remove them from your views they remain in the system's cache.
Without seeing your code it is not possible to say more than this.
Related
Throughout all the betas of Watchkit I was able to run my watch app seamlessly, but with the recent release this past week (8.2) my willActivate method is hardly ever called. What happens is awakeWithContext gets called and the watch stalls with the spinner spinning forever. Has this issue happened to anyone?
I've found that locking and unlocking the device (simulator) by typing Command-L will cause the willActivate method to be called. I hope you don't have to do that on a real Apple Watch.
Just came into the same problem yesterday.
In my case, I'm using the page navigation, and the initial view controller's awakeWithContext gets called, but willActivate is never called.
After some digging I found out that when using page navigation, ALL of the pages awakeWithContext will be called at launch time and before the initial page's willActivate. If one of the pages awakeWithContext method get stuck, the initial page's willActivate method will never be called.
You may need to check your other view controller's awakeWithContext methods to see if they are stuck.
So, I still don't think I know exactly what is going on or what's causing it, but I'm having the exact same issue, and I have done some investigating and have some results, so I hope this helps us narrow this down. I have identified that it has something to do with the complexity of the layout that is going into my initial controller. If I change to a simpler layout for my initial controller, or if I delete "enough things" from my initial controller, then I no longer get the spinning wheel of death. (Of course that also breaks the logic of my app). My layout is a bit complex, but not that complex; there are groups nested 4 layers deep, and about 20 total UI elements (including the groups themselves), with four buttons and 4 labels. It seemed to work fine in the beta. And there's not a clear rhyme or reason to it; some combinations of layouts seem to cause it, some don't. It is deterministic; if a given layout spins on load it will always spin on load, and if it doesn't, it doesn't. When it spins, I never get willActivate. When it doesn't, I do. It does not seem to have anything to do with the contents of awakeFromContext:. I can delete everything from that method and it does not help. It also has nothing to do with assets, compiler settings, etc., etc. Other than that, I haven't figured it out yet. If anyone has any insight into this, I would love to hear it.
So I have just completed coding an application in xCode 5.1.1 running on a iOS 7 device (App is ARC Enabled). Everything is complete and no crashes are occurring but I want to make sure the application is problem free before submitting it for review.
I have put log statements in each of my view controllers DEALLOC methods to make sure they are being called..not one of them is being called, ever! Not sure if this is how it is supposed to be in an ARC-Enabled application? Also, it worries me because when I run the application and switch to the "Debug Navigator" tab the memory usage of the app continues to increase, as if view controllers are not being released after they are dismissed or a push/modal segue happens. Any help or thoughts would be greatly appreciated on the matter.
Thanks.
Looks like you are having strong references to view controllers that you are not aware of. Use the static analyser to warn you about any reference cycles. In general, look at warnings and fix them. You may have things stuck in an NSArray unexpectedly. Check all variables holding these view controllers, are there any stored in objects, that you might have to change to nil?
I was working with a project in Xcode 4.2, which is not using any storyboards but normal xib's.
ARC was working super fine and was happy with that, No problems.
Now the Odd problem araised when I upgraded from Xcode 4.2 to Xcode 5 (Still not using storyboards).
I pop a screen using 'popViewControllerAnimated' function, and obviously, the Screen is popped.
But when I analyzed on the memory allocation, I found that the screen memory is not released even after the screen is popped.
Moreover, when I open that screen again, memory is allocated and not released even when I close it.
Seems more like a retain cycle, but I'm damn sure that I've never used 'retain'.
Now I've upgraded to Xcode 5.1.1 and this Odd issue, still persists.
To convert my project to 'Storyboard' design is a complete burden for me thats why I'm preserving ordinary xib's.
I'm now tired of Google'ing and searching all the forums including Stackoverflow.com.
Guys, Please help me figure out the issue.
Its a life Saver for me.
ARC is not magic. ARC keeps track of strong references to objects. When the number of strong (owning) references to an object drops to zero, the object gets deallocated.
If one of your view controllers is not being released, it means there is a strong reference to it somewhere. One possibility is a "retain cycle", where 2 objects each have strong references to each other. This happens when you do things like have an object that owns another helper object, and the helper object has a (strong) pointer back to the owning object. The usual solution is to make owners keep strong references to their objects, and owned-to-owning pointers weak (like delegates).
There is no way for SO readers to find your problem for you.
Have you tried running the analyze tool on your code? It may point to the problem for you. You should also run the program through the Leaks instrument as Phillip suggested. Both of those tools are very helpful, although neither is 100% foolproof.
Failing that, you might need to find a senior-level iOS developer with whom you can sit down and do a code review. Often, in the process of explaining the logic and implementation of your program to somebody else, you find the problem yourself.
Check if you are setting in one view controller as the delegate of the popped view controller. Because when that popped view controller is dismissed, you must set the delegate to nil. Is common to forget this.
In developing my current app, I ran into some issues that I eventually traced back to a low memory warning. Part of the low memory is coming from my (liberal) use of UIWebViews, which are apparently consuming a lot of memory.
I didn't think this would be an issue, since a view that isn't currently visible should just vanish when the low memory warning is thrown, unfortunately it turns out that anything connected to the UITabBarController remains in the heirarchy and doesn't release. By manually releasing (and then recreating in viewWillAppear) the views, I make things work decently. But it doesn't completely solve the memory warning issue.
So what I need to do is manually release the view -- and the large amount of memory that winds up connected to it -- and then restore it. Since I don't want to build it programmatically (that's what IB is for!), I need to somehow reload it from storyboard.
Or, alternatively, I'm being an idiot and there's something really obvious to make my life easy.
After more experimentation, it turns out that on the one hand, my understanding of view life cycles was slightly flawed, and on the other my experiments were tainted by having accidentally let zombie objects on.
Views will, in fact, unload their contents in a low memory condition and reload them later -- that's part of what 'viewDidLoad' and 'viewDidUnload' are designed for! Putting init code in them, as some tutorials I read did, was a major error. That init code should go in the designated initializer -- even if that can be annoying to figure out which initializer is designated.
I'm making an app that has a few view controllers with UIDatePicker controls.
After having lots of memory warnings, I've done a lot of debugging on the cause. Using instruments, I was able to see that whenever a view controller containing a UIDatePicker appeared, memory usage was going up by 2-3mb. Ultimately, this leads to a memory warning. While I can do so much in here, and have seen a dramatic decrease in crashes since re-writing these functions, I'm still not comfortable with this behaviour and want to fix it.
The UIDatePicker's are part of the XIB file. I've tried taking them out of the XIB and programmatically adding them. This doesn't solve the problem. I've also tried using a (thread-safe" singleton. This limits memory usage to only one instance (so memory usage doesn't increase), but I'm trying to avoid singletons wherever possible. Should I just suck it up and use a singleton?
I'm seeing this behaviour on iOS 5 and 4.3, across all devices that run it. I'm using ARC, as the title suggests.
Instruments does not show any memory leaks.
Here is a screenshot from Instruments. Each step up in usage is when a VC containing a date picker appears. The baseline at the start of the graph is 2.3mb of memory usage.
http://i.stack.imgur.com/1S7ns.png
Cheers!
The tool you want to use here is called heapshot. It will help you narrow down the types of objects that are being incorrectly held onto. As #sudo notes, the problem is probably in your delegate rather than the date picker itself. You're probably not "leaking" in the strictest sense of the term. You're probably just holding onto memory that you didn't mean to (which looks a lot like a leak).
You should take a careful look at whether you have any circular strong references. Do you have objects that have a strong reference to their delegate for instance? That will typically lead to a retain loop (which will never be released under ARC). Heapshot can help you find these objects.
I seem to have solved my own question. As this was an inputView, and I also had a UIToolbar with a "Done" button as the inputAccessoryView.
So now I create these programatically in viewWillAppear. In viewWillDisappear, I set the UITextField's inputView and inputAccessoryView to nil, and the date picker and date picker toolbar to nil.
They are no longer in the XIB file.This seems to work really well - memory spikes up by 3mb, then goes back down the second the views disappear. Now the app is running consistently at under 10mb of live memory - it spikes up to 15mb on occasion but very rarely.
Thanks for the help sudo rm -rf and Rob - heapshot analysis helped to try and get to the bottom of it.