Get count of UIView instances shown on the UI - uiview

Is there a way to count the number of UIView instances created on UI without changing too much code? I need to improve performance, I feel some of the UIView instances are untracked.
Is there a way to create an extension of UIView and always return the number of live UIViews?
Thanks!

I suggest you use Profiler tool to track the allocated UIView objects and check memory leaks.
Also if you like to visually check where your UIViews are located you can use
"Debug View Hierarchy" tool.

Related

UIView field not allocating memory in iOS

I have just started with iOS development in objective C and I'm finding it difficult to get my head around UIView objects.
Here is what I'm doing:
In an existing project, I'm adding a new UIViewController.
In a storyboard I'm dragging and dropping UI elements.
I added some constraints into each of the UI elements (just playing around, there is no specific constraint as such, this could be anything).
Dragging each of these UIElement to ViewController.h to create a handler.
In ViewController.m file I'm trying to first synthesize all those objects and then further play around with some logics (again nothing very specific).
In ViewDidLoad I'm try to perform loading my UI elements.
During runtime when I trigger my custom UIViewController, then I could see from debugger that it actually comes into controller's ViewDidLoad section.
Problem:
During runtime, all the UI elements have nil assign to them. I don't understand this that why is synthesize not allocating them any memory. The execution just goes over my logics, but does nothing. I don't see anything displayed in my screen.
Question:
Why is this so? Why even after setting my UI constraints in storyboard and synthesizing each UI handler objects, I was not able to allocate memory to my UI objects?

How to release a `Hidden` UIView from memory?

I'm used to setting up views in StoryBoard and set inactivated views as Hidden, but I also don't want them to take up too much unnecessary memory. How to release a UIView when it is hidden or inactive?
By the way I'm programming in Swift. Thanks in advance.
I am agreed with The Paramagnetic Croissant. But if you want to remove it then you can use:
YourView.removeFromSuperview()
If you want to inactivate the views forever, you need to remove them from their superviews (view.removeFromSuperview() will do the job for you here). Otherwise it wouldn't make much sense to release it from memory since you'll have to reinstantiate the same view later on again which in my opinion is unnecessary overhead compared to just hiding and unhiding it.

how to detect interface changes on iOS application

Is there any possible way to detect every change on User Interface during runtime??
I'm trying to find all objects in the current app interface.
I'm trying to to get all nodes inspecting recursively the main Window, but, for example, how to know if the top viewcontroller changes or if it's added a uiview dynamically, or is presented a modalview??
The main objective is to have a library to do this..
Any idea, help?
Thanks!
You could write your own library based on this, using advanced Objective-C techniques. I do not recommend you to do this, since it mostly breaks MVC patterns on iOS. Depends on what do you want to use it for, maybe analytics?
So these are the options I believe, if you want to actively inspect UIView hierarchy. All options are pretty complicated though.
Swizzle methods such as addSubview and removeFromSuperview of UIView, so you could know when changes like that happens. Including the getters of frame and bounds, if you wish to know the position.
You could use KVO to watch properties such as: subviews, frame, bounds, superview to notice any changes. But at one point you would have to add the same object as the observer (could be singleton).
Decide for an interval that is fired by a NSTimer and go through the hierarchy recursively beginning at keyWindow on UIApplication. This would have a big performance impact though.
There may be other options, but these are the ones I believe to be the best choices.

How to resolve memory crash

I'm creating an application which features having multiple animations.
There are 50 pages and on each page there is a different animation and each animation uses many images.
I'm using UIPresentModelViewController for presenting the views and
am changing images using NSTimer.
When I swipe continuously the application crashes with this message:-
Program received signal: “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'.
(Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")
I searched a lot but couldn't find any proper solutions to this issue.
Just check within your code that you are making some mistake by adding new view every time but forgot to release it...
You need to look at (and perhaps post) the stack trace when you crash. And the code that changes the image. This sounds like memory bloat (not a true leak in that someone is still referring to memory). The Analyze menu item might catch something (and you should definitely run it), but you may need to run the Allocation instrument and look at heap checks. See http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ for more.
This sounds like a stack overflow to me. In the "Other C Flags" section of the project's C/C++ language settings add a flag for "-fstack-check" and see if that turns up any unwanted recursion.
Signal 0 is usually due to memory low as the app using too much memory. Check whether memory warning method is called or not.
The data formatter thingy failed to load might be due to there's not enough memory to load it..
50 views like you describe sounds like a big memory hog. So I suspect memory management is unloading some views. Then when your program needs the views, they are not there and your program crashes. The error message doesn't quite fit this, but it may not be accurately telling you what the problem is.
Consider the following possible scenario, and see if it fits how you coded this program.
In order for the OS to manage memory, it can unload views and reload them as needed. When this is done, the methods viewDidUnload, loadView, and viewDidLoad are called.
viewDidUnload:
This method is called as a counterpart to the viewDidLoad method. It is called during low-memory conditions when the view controller needs to release its view and any objects associated with that view to free up memory. Because view controllers often store references to views and other view-related objects, you should use this method to relinquish ownership in those objects so that the memory for them can be reclaimed. You should do this only for objects that you can easily recreate later, either in your viewDidLoad method or from other parts of your application. You should not use this method to release user data or any other information that cannot be easily recreated.
loadView:
The view controller calls this method when the view property is requested but is currently nil. If you create your views manually, you must override this method and use it to create your views. If you use Interface Builder to create your views and initialize the view controller—that is, you initialize the view using the initWithNibName:bundle: method, set the nibName and nibBundle properties directly, or create both your views and view controller in Interface Builder—then you must not override this method.
Check the UIView Class Reference --
viewDidLoad:
This method is called after the view controller has loaded its associated views into memory. This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method. This method is most commonly used to perform additional initialization steps on views that are loaded from nib files.
You may have inadvertently initialized these views in your init methods rather than in your loadView methods. If you did this, then when the OS unloads a view (you will see viewDidUnload is called) the memory associated with the view and all subviews (all of the images and animations) will be unloaded. This saves memory, but when you need one of those unloaded views to reappear, loadView will be called first if the view had been previously unloaded. If your view setup is done in the init methods rather than in loadView, then the view will not be setup again. But if the view setup is done in loadView method, it can be recovered after memory management unloads it.
There is one and easy way to find out leaks that is hard to find via leaks instruments and so on - Zombies analyser. It shows every unlinked memory in your program, and you can easily detect leaks and optimize code in minutes.
If you're using lots of images for a single animation you're doing it wrong. You should have one, or several very large images and then just show a portion of that image. This way you can load very few images, but have the same affect of having many images.
Look into cocos2d or other frameworks that are popular for making games, as they will be much more efficient for animations than just UIKit.
Find out the reason for memory crash using instrument tool and then refactor the code with best practises with recommended design pattern. There is no unique solution for this. Thanks.

Where to place the code to change the properties of a UIView

If I'm creating a UIView programmatically and I wish to change the UIView properties (background, for example, or actually, messing with CALayers), must I place the code outside of UIView such as in the View controller? Can I put the code somewhere inside UIView?
I was checking out the CoreAnimationKioskStyleMenu example, its code is inside UIView but it's loaded from Nib and can be placed at awakeFromNib, so it doesn't seem to apply to my case.
That depends. Obviously, a good way to handle this is to use a xib file, as it is designed to hold data like this, but that isn't always the best answer for every situation.
If the view is meant to be reused frequently (like a button, or some widget) throughout the application, its best to store all that customization in a subclass of the UIView.
If its a single larger view that will always be managed by a UIViewController, you can keep some of the information in the UIViewController. However, if you end up subclassing a UIView anyway it's probably best practice to keep the data in the UIView.
As a general note, I believe its worth your time to push as much of this data into a xib using interface builder. Magic values (like colors or sizes) peppered through your code will always be a problem if you want to modify it. I have found modifying a xib to be much easier.
Actually there are some methods where you could place initialization/ customization code.
(void)willMoveToSuperview:(UIView *)newSuperview;
(void)didMoveToSuperview;
will get called as soon as u add the view as a subview to another view, at which point you already have the frame and all the properties, and you can do further customizing as you wish.
(void)layoutSubviews -- generally used for changing subviews' frames and layout organization.
Will get called each time the view needs to be redrawn by the system, or when you specifically call [self setNeedsLayout] on your UIView.
Hope this helps.

Resources