I'm still a newb to objective C and Xcode 5. I have made a simple game and was performing some analysis on the game's memory leaks using one of Xcode's built in performance tools (Cmd+I). To make the game I was using cocos2D framework.
Now it looks like I had quite a few memory leaks (screenshot below). A few things I wanted to address were (keep in mind it's a really small game)
Are the memory leaks being shown significant? Or is it normal to have a few memory leaks in the bytes-kbytes range?
Many of them are "Malloc -" and have no trace in the Extended Detail view. How do you deal with these?
I know Xcode has the option to turn on Objective-C ARC. Would it be a better idea for me to just turn that on instead of worrying about keeping track of memory leaks and all of that? (keep in mind I'm a newb)
Thanks, here's the screenshot!
I think the more important thing about memory leaks is how often does it occur. If it happens on app load once, i don't think it will matter that much, but if it happens in a loop or after every user action then I think it is something to be worried about.
And I definitely recommend using ARC, that question has been posted to SO many times, here you can find better answers than I could ever give.
ARC, worth it or not?
To ARC or not to ARC? What are the pros and cons?
To use Automatic Reference Counting or not to use
Related
I would like to make a 2D iPhone game, I've done some research and Cocos2D does seem like the best option, I am just wondering how much knowledge of Objective-C I will need before tackling Cocos2D. I know the fundamentals of programming in Objective-C - I can make a basic command line tool app. I've done some iOS SDK tutorials but I wouldn't know how to make an iOS app if I was asked because the tutorials I'm currently following are about three years old.
What is required as prior learning before using Cocos2D and does anyone know of any good resources? I'm more of a visual learner so I find videos more helpful than books or blog posts.
Thank you in advance for your time and any help :)
There is no required prior learning. Use it. If you get stuck on something, look it up, google it, or ask a question.
Meaning: don't waste your time learning general concepts without actually being in the situation of having to apply them.
Analogy: you don't need a PhD in mechanical engineering to drive a car - though it might help when you run into any issues. But in such a case just do what 99% of all people do: call for help. It hardly makes any sense to first learn the potential problems you can have with a car, you deal with them as they happen.
Also: frustration is part of the game and can not be avoided. :)
how much knowledge of Objective-C I will need
A lot. You need to master Objective-C before trying to make a bigger project like this.
And to understand Objective-C, you need to have a very solid knowledge of C.
(Also, for using 3rd-party frameworks lile Cocos2D, make sure you understand well the basic, default libraries such as Foundation and UIKit.)
For making games like Free flow , having an intermediate knowledge of Objective-C is sufficient. But if you plan on make something like Temple Run, then you need really good knowledge of Objective -C,Open-Gl and cocos2d..
The site I would recommend is raywenderlich.com, that's where i started from and they have tutorials from really basic level to really advanced level.
Hope this helps
The answer to that depends truly on who you are, your work ethics, and how much effort your are ready to consent to that effort. I would argue that if you have solid foundations with other OO language/frameworks, your quest is possible. I would start by 'repurposing' a freely available game ( you will find many good examples and tutorials from Ray Wenderlich and also Steffen Itterheim. Pick a sample project that is not too 'distant' from your game specification, and repurpose it. In doing so, you will break-in to objective-C and some of the basic frameworks you need to comprehend. Mastery will follow if you are dedicated and stick to it. Also, SO rules : many answers are available here : appropriate questions will yield many helpful hints and solutions to point problems.
ps. My biggest learning curve turned out to be xCode, a truly arcane and dogma-ladden IDE. I since switched to another IDE and my productivity has gone back to respectable levels.
I recently picked up Objective-C and cocos2d at the same time. I did a lot of reading about objective-c in the beginning to give me a primer. Aside from the syntax, most of that knowledge remains unused in my game. The most important things to learn about objective-c before starting in on cocos2d tutorials are, memory management, and debugging.
The reference count memory management might take a minute to get used to depending on what languages you are coming from. The general rule is, if you alloced/copied (without autorelease) or retained it, you must at some point release it, and if you need to use something beyond the current scope, you should retain it. You can see from some cocos2d examples of overwriting an objects dealloc method in order to dealloc anything you created/retained.
The debugging took me a minute to get used to as well. It helps if you add a high level try/catch block that you can use to log uncaught exceptions, otherwise some of your errors will give you little info to go on. You may also want to research/mess with some of your project settings to allow for better bug catching, such as enabling zombies. A big causer of crashes in objective-c is sending messages to already dealloced objects. Once you come across a badaccess error that you can't figure out, you will basically be forced to get knee deep in this stuff in order to figure out the cause.
Some other purely objective-c knowledge that will come in handy are getting very familiar with how NSArray and NSDictionary objects work, how they automatically retain/release, and how they can only hold objects (no primitive values). To work with floats/int and arrays/dictionaries, you need to convert primitives into something like an NSNumber object, which can be done fairly easily with a little research. Another helpful too is knowing how to save/load plists. There are convenience methods for doing this on NSArray and NSDictionary objects. This along with a little knowledge of the NSFileManager should be enough to help you save/load game states. If you want to get really fancy/clean in your coding, you will also learn about observers in objective-c. KVO can be great for making your UI update automatically on a certain objects property changes. For instance, my HUD KVOs the player object's life, so that when the life value changes, the HUD automatically updates. This can allow you to make a cleaner MVC type application. You can also register to listen to other types of messages (not just property changes), just make sure to unregister your listeners when you are done listening.
My last bit of advice would be to always pay attention to XCode warnings. If you are getting one, and you don't know why, you should figure out why. Some simple ones you might be able to ignore, others may cause bugs that you will not be able to track down any other way. For instance, I once used the function max() in my code, and xcode gave me a strange warning that I didn't understand. This caused havoc on my program by corrupting the stack. When I changed max() to MAX(), three or four unexplained bugs instantly disappeared. This kind of thing can set you back weeks, and take serious combing through every piece of your code if you don't catch it right away.
The rest can mostly be learned by looking at cocos2d code/examples. Good luck.
My app runs slow after I spend 2 days changing it to work with ARC.
Dose I make some mistake to make it slow?
Or ARC is a little slow?
It’s practically impossible to feel a difference after doing a correct conversion to ARC. Remember that ARC is not a garbage collector, it’s almost like if the compiler placed the manual memory management calls into the source code for you (= no extra runtime overhead).
Are you sure about the performance difference? Can you measure it against the older code revison? Did you profile the new code in Instruments for memory leaks? Why did it take two days to convert the code, did the automatic Xcode conversion not work for you? Why?
I wonder how the professional application that provided to customer is such elegant , smooth and less or no application crash. because I always see the problem is mostly about memory leaking, NSZombie or not good enough performance.
I see it's great to fix some problem with Instruments Tool. But I just be familiar with memory leaks and zombie template. Of course, I think there are other interesting tool to trace and fix our application better. (System usage, Automation Testing, etc.. Any ideas?)
My question : What's the best strategy to sharp your application with Instruments? Recommend instruments template or any suggestion?
Let's share your experience and discuss!
*UPDATE : * May I ask more question, Should I edit this question to the wiki? It should be more than question that we can share strategy.
I mainly (about 98.2% of the time) use the Leaks and Allocations templates. Also, many people don't know - but in Xcode 4, you can start the app using instruments right from Xcode. From the top menu, just choose Product -> Profile.
Also - even when using ARC, you should still be conscious of how you are using memory and how you are allocating objects. Many times, ARC was doing its thing just fine and yet a small programming change in my code resulted in much less allocated objects. ARC will help you when writing code, but it is not an excuse for not testing and profiling your applications to make them as efficient as possible.
Yes, Instruments is critical. ARC mitigates some of the worst memory problems. Analyze (on Product menu) is also under-appreciated, too.
Check out program 123, Improving the Stability of Your Apps, in WWDC 2011 in the App Frameworks section, which has a nice discussion of other issues that can affect the stability of your code (I especially think the discussion of testing is good).
Finally, elegance is not a product of a tool, but rather of good design. It takes a surprisingly amount of work to make a product that is elegant. Embrace the HIG and the broader philosophical themes contained therein. Also, do code and design reviews with developers that you respect.
The CPU sampler (Time Profiler) will tell you where your program is spending its execution time. If your app is 'slow', this instrument can often help you determine where the problem time consumers are, and (if you understand your program) how you can remedy those problems.
Run this instrument regularly in order to understand your programs as well as the implementations behind the abstractions they depend on -- don't wait until a problem arises.
You can use the CPU sampler to record the callstacks of your programs' threads. This is recorded at a high frequency. The sampler displays information such as the functions that are taking the most time and what percentage of the time they are taking. You can charge libraries or functions to their callers, effectively choosing the granularity you'd like, or hiding what you cannot alter. Once you've found the functions/methods you are interested in, you can view the source file in Instruments, and it will break down what's taking so long for you.
Apple introduced sweet feature called Automatic Reference Counting(ARC) that makes almost all memory control for you. You just need to set weak/strong parameter of properties. And it eliminates almost all problems with memory leaks.
And as for tools - I don't know any other app other than Instruments. Instruments has all... Instruments:) I need, to do tests with.
After migrating my app to ARC using the migration tool and resolving all pending issues a quick test in the Allocation instrument revealed that pretty much anything I do in the app is leaking memory.
It's a pretty big app and migration took 2 hours to complete (including checking every change which I did - all of them looked fine!)
I checked all the compiler flags twice to make sure ARC is really enabled for every file and on the project level.
Previously to migrating to ARC my app was totally fine. There was absolutely no heap growth when taking Heapshots by repeating the same action multiple times. It was 100% leak-free, there was no abandoned memory. It was perfect. Now it's one huge leaking thing like if there was no tomorrow.
Any idea what's going on?
You haven't shown any code here to highlight parts of your application that are causing objects to accumulate in memory, so it's hard to provide a specific answer to your situation. However, there are some broad suggestions that I can provide based on my experience in migrating several projects across on Mac and iOS.
In another answer, I describe in detail several areas of memory management that you'll still need to watch out for under automatic reference counting. The primary concerns here are retain cycles and Core Foundation objects (or other non-Objective-C memory allocation).
Given that you had an application which did not accumulate memory on repeat actions before and was cleanly ported through the ARC migration tool, retain cycles are more likely the problem than improper bridging, etc. with Core Foundation. The migration tool tends to highlight problematic areas with Core Foundation and catch those before they become an issue. How to deal with them may be tricky, but you at least know they're there.
Retain cycles can be subtle bugs to track down. Look for delegates that are set using strong instance variables or properties, rather than weak or unsafe-unretained ones. Examine your use of blocks or block-based notification observers, because they can hold on to references to the objects that create them (particularly in the case of the observers) and create cycles. Check for objects further down a navigation hierarchy that use strong references to point to ones higher up.
Use Instruments to track down the specific objects that are accumulating via the Leaks and Allocations tools. In the latter, use heap shots between repeated actions to see which objects are created and still alive after each pass. You should also be able to identify where those objects are allocated, hopefully leading back to what's grabbing an incorrect strong reference.
The Leaks instrument has a new retain cycles detector, which can be seen by going to the lower panel and changing the "Leaks" popup to "Cycles & Roots". This doesn't catch everything, but it can help.
I've now moved multiple projects on Mac and iOS to ARC, including Mac applications that had been using GC, and in each case the applications have been better off for it. The process has exposed bugs that I had missed for years in my memory management, cut on average ~3% of my project code, and has led to some significant performance increases in my previously garbage collected Mac applications (I haven't benchmarked my iOS ones yet).
Background: I'm (jumping on the bandwagon and) starting learning about iPhone/iPad development and Objective-C. I have a great background in web development and most of my programming is done in javascript (no libraries), Ruby, and PHP.
Question: I'm learning about allocating and releasing memory in Objective-C, and I see it as quite a tricky task to layer on top of actually getting the farking thing to run. I'm trying to get a sense of applications that are out there and what will happen with a poorly memory-managed program.
A) Are apps usually released with no memory leaks? Is this a feasible goal, or do people more realistically just excise the worst offenders and that's ok?
B) If I make a NSString for a title of a view, let's say, and forget to deallocate it it, does this really only become a problem if I recreate that string repeatedly? I imagine what I'm doing is creating an overhead of the memory needed to store that string, so it's probably quite piddling (a few bytes?) However if I have a rapidly looping cycle in a game that 'leaks' an int every cycle or something, that would overflow the app quite quickly. Are these assumptions correct?
Sorry if this isn't up the community-wiki alley, I'm just trying to get a handle on how to think about memory and how careful I'll need to be. Any anecdotes or App Store-submitted app experiences would be awesome to hear as well.
I've taught courses on Cocoa development, and memory management is the second thing I teach (the first being C pointers). My experience has been that if a Cocoa programmer doesn't understand memory management, then he never amounts to much of a Cocoa programmer.
In other words, learn memory management. You won't regret it.
Follow the patterns, and memory management is rarely the biggest roadblock in Cocoa.
However, I'm going to be a contrarian here: your sense is mostly correct. Leaking one NSString used as a label somewhere is not going to hurt anybody. Most apps of any complexity have multiple singletons around in the world holding state for the entire life of the app, and that's OK too (well, better, because it's explicit). So no, accidentally leaking a string once isn't going to kill you. Leaking big things (images, textures, file content data) will hurt you, though-- Apple doesn't guarantee any minimum or deterministic amount of memory for your process on the iPhone OS platform, so one or two of those leaks might result in users seeing frequent "crashes" in the field that you don't always see during development.
Be vigilant, use the patterns, and use the tools, and you'll be OK.
Your should never leak memory.
Consider: You today write some code that leaks memory only once during the execution of a program. Tomorrow, you reuse that code in some other way and it is executed many times. The leak is then problematic. Finding that leak may be very difficult. Much more difficult than making sure to always free your memory the first time you wrote the code.
Save yourself and others a headache down the road: always free your memory.
It is very important. Apple offers a tool for memory leak detection called Instruments.
This topic has previously bean discussed here as well: Memory leak detection tools in XCode
More important than life itself :p
Seriously though, just follow the rules in the links below and you'll be ok.
It becomes second nature after a while.
http://theuntitledblog.com/2010/05/25/objective-c-memory-management-rules/
http://developer.apple.com/iphone/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html