I've having some memory issues using ARC in Xcode 5.1.1. I've got several full-screen images in Storyboard in UIImageViews and each time it segues into that View, the image is reloaded and never released resulting in obvious memory problems.
Whats the best way to release those images in the UIImageViews?
This might seem like it could be a duplicate question of other problems, but I think mine is a bit more specific than others I've seen on SO. If you can find an exact duplicate question though, I would love for you to comment that in!
edit: I was using pushViewController instead of popToRootViewController.
After several hours of checking and double checking all my code and researching online, I finally was able to discover my problem. I had accidentally had my custom Segue to infinitely stack on my Navigation Controller by
pushViewController
instead of
popToRootViewController
which would be the proper way to automatically release that View.
I thought about deleting this question since it didn't get a final answer, and the solution was so simple, but I decided to answer it myself and maybe someone with a similar problem as me will find this and be reminded to check out their custom Segues!
Related
I am making a iPhone app, I am currently using iAd's in my view's. I've read something about apple recommending to share the adbanner's through out the view's. How can i do this because I have read the apple documentation and it was not clear enough and i was confused, please help me, if their are any tutorials please tell me or just answer and point me in the right way. Currently I have a ad for every view controller and it runs nice but it comes with a error: Too many active banners (10). Creation of new banners will be throttled.
Please help, i am using storyboards and the latest Xcode :) thanks
The way I do it is use a Singleton class that creates the adView, this way you only ever get 1 adView. Then in your viewDidAppear methods of all your ViewControllers you simply add the adView to your view.
You can see my code in the accepted answer here although that is for an AdWhirl ad view, it shouldn't be too difficult to change it for an iAd ad view.
This is the perfect case for a singleton. Many have simply made a subclass of ADBannerView, which can then be added to your view in -viewDidLoad (or -viewDidAppear with the proper precautions taken) and removed in -viewDidDisappear for each View Controller.
I am using the Apple UIPageViewController template from Xcode to create interactive photobooks. Everything works fine except that whenever I turn a page (create a new viewcontroller) the memory allocation goes up and up and up until the app crashes. It looks to me that the viewcontrollers never get 'released' (am I still allowed to use that word in an ARC environment?). It does not seem to be anything to do with the content of the pages because when I comment out all the content creation stuff in the ...DataViewController the memory still keeps going up and up every time I turn a page, not as spectacular as when a large image has been included but it still keeps creeping up.
There's been exactly the same question here: PageViewController: How to release ViewControllers added to it? but this one deals with a pre arc & storyboard situation. Adding autorelease is not permitted and it certainly seems that the compiler is NOT taking care of it. :-(
Any suggestions?
The problem turned out to be the never enough damned "UIImage imagedNamed" construct. It probably is all my own fault for not checking after I read somewhere that this had been fixed in a recent xcode release. So I assumed images were no longer being cached whereas the opposite was true. Once I changed all to the "UIImage imageWithContentsOfFile" the app started working smooth as a babies bottom.
I had the same problem building a picture book with very large images. I went to other question you provided a link for and that solved it for me. Adding "autorelease" frees up the memory.
In the UIPageviewcontroller delegate method "viewControllerAtIndex". I changed from:
// Create a new view controller and pass suitable data.
ContentViewController *contentViewController = [[ContentViewController alloc] initWithNibName:#"ContentViewController" bundle:nil];
and added autorelease
// Create a new view controller and pass suitable data.
ContentViewController *contentViewController = [[[ContentViewController alloc] initWithNibName:#"ContentViewController" bundle:nil] autorelease] ;
This wasn't included in the apple example but I'm also using xib for each page. I've been debugging this using instruments and saw memory reclaimed right away and dealloc being called when it wasn't previously.
found answer here....
https://stackoverflow.com/a/7934392/1212585
I'm writing a navigation app for iPhone at the moment and I'm having a very weird crash issue and was wondering if anyone had come across (and solved) this issue.
I have two views, both of which contain UITableViews and one that uses cells loaded from a nib. When I push and pop from one view to the other, after a couple of presses (usually 7 to 10) with everything loading and displaying as it should the app suddenly crashes. The debugger shows that CALayer was the last thing running, but I don't use any custom implementation of this class.
My first thought is that I've over-released an object, but after two days of playing with the code I can't identify any zombies.
Does anyone know what's going on here? Can post parts of code if required.
UPDATE:
Looks like zombies are being created on UIView delegate methods, namely viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear. Will investigate further tomorrow. :D
What you can do is to set breakpoints at the dealloc methods of the related classes, and see if the crash happens in one of the method. And also usually by looking at the callstack when the crash is happening, you can tell whether it's a memory related crash or not.
I'm new to iOS development, obviously, and I'm running into a bit of an issue with many of the tutorials that I find online. While I understand the majority of the code that is going into these programs, I cannot figure out how to translate this one fact, which is probably simple.
Many tutorials either use the Navigation-based template or View-based template, but I would like to try building tab bar applications. Tutorials either use the App Delegate or rootViewController (being the navigation controller), but since my tab bar is my rootViewController, I always run into an issue. I'm also unable to use the applicationDidFinishLaunching method in most of my code, because it technically only applies to the first tab at launch.
These are my questions:
Is there a way to "translate" these files into new classes (for example, creating an instance of NSObject for the App Delegate code for each individual tab or creating instances of UINavigationViewController)?
If I can create the instance of NSObject, how do I ensure that the code links up to the objects that I create in my viewController?
If I can create a file that uses UINavigationController, how do I trick the program into temporarily allowing the Nav Controller to be the rootViewController.
Many thanks in advance!
Right off the top of my head, I can only answer number 3 for you, you could do that in one of two ways that I am aware, and if anyone sees either of these is incorrect or bad practice, I hope someone corrects me, as this is what I have been doing.
[appDelegate.window addSubview:appDelegate.newRootViewController.view];
appDelegate.window.rootViewController = appDelegate.newRootViewController;
or
[self.navigationController pushViewController:appDelegate.newRootViewController animated:YES];
Both should accomplish the same thing, though if you can help it, the second version is ideal. Its also worth noting that for the first one, there is no tricking, you are actually setting the rootViewController of your app to something different.
I'll do some digging and see if I can answer any of your other questions for you too.
Edit: So after re-reading and thinking a bit more about it, I think the other two questions can be answered by maybe clarifying a tab bar application. Unfortunately, I'm fairly new to iOS as well, and I haven't had to opportunity to create a tab bar application, so I don't want to give you incorrect info. I would recommend checking out http://www.techotopia.com/index.php/Creating_an_iOS_4_iPhone_Multiview_Application_using_the_Tab_Bar_%28Xcode_4%29 and hopefully it can give you a little bit of a better idea of how Tab Bar Apps work. I've been using that eBook along with another from that site combined with Ray Wenderlich's tutorials to teach myself.
Anyways, I hope this helps to some extent, if you want me to try to clarify or go into detail on anything just comment and I'll see if I can help.
Good Luck!
-Karoly
You're misunderstanding how the app delegate works.
It's the delegate for the application, not a controller. Your controllers may be loaded from a xib by the time applicationDidFinishLaunching is called, but there's no connection between the two events.
applicationDidFinishLaunching is just the place where you do final setup before the app is ready for use.
If you don't instantiate your tab bar controller in your main xib file, you can instantiate it here, then instantiate all of it's controllers and add them to to the tab bar controller. While you're doing that, you can load plists, set properties on the controllers, etc.
If you do instantiate your tab bar controller in your main xib file, you can still get access to its controllers here. You can edit those controllers or throw them out and create new ones. You can even throw out your tab bar controller and switch to a navigation controller.
I can't answer questions 1 and 2 because the assumptions behind them are invalid.
Rather than ask how you work around perceived problems with the app delegate and tab bar controllers, describe what you're trying to accomplish.
I have been struggling with this issue for a while and i noticed that many people came across the same thing by reading many posts here and on other forums. Just this morning i realised what i was doing wrong and i thought of sharing it just in case someone stumbles over it in the future.
the problem in my implementation was that within viewDidLoad of view controller (VC1) i was setting its view property to a new view controller (VC2) which forces i believe the framework to exit viewDidLoad of VC1 without reaching its end, hence not calling the consequent delegate function of the view controller: viewWillAppear, viewWillDisappear, viewWillAppear, and viewWillDisappear!
So my solution was to delay all the code that has to do with creating and setting VC2 to be called from within viewDidAppear instead of viewDidLoad. If you do it from viewWillAppear you will get to the same trouble.
Hope it helps
AF
Why would you go to all this bother just to save the memory of a UIViewController?
sizeof(UIViewController) gives 132 bytes. Even knowing that a view controller will create a fair few support objects so it's going to take up more memory than that this is a fantastic example of premature optimization.
I'd give it a fair chance that the code solution you have gone for will :
(a) leak memory in edge cases
(b) fail on further updates to iOS
(c) be a nightmare to debug by any coder other than yourself
(d) be a nightmare to debug by yourself in more than a few weeks
Why not just write your app using the frameworks provided and profile it - if this tiny amount of memory is causing you problems the fine, implement your solution. If not, leave well alone.