Best practice testing the iOS application development with Instruments - objective-c

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.

Related

Analyzing memory leaks in Xcode 5

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

Why is my app full of memory leaks after migrating to ARC?

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).

Code readability and UI design balance

I have worked a lot on improving how my code runs (and it's "beauty"), but when is the time to stop fixing, and start working on the UI?
Microsoft (in my opinion) seems to go with the nice-code, while Apple goes with nice UI (although Apple's developer examples do have very nice code).
I'm bad at balancing, when is it the time to work on one or the other?
Make it work, then make it elegant, then make it fast.
If the user doesn't like the program, the quality of the code is irrelevant. Once the user likes the program, then code quality becomes more important. And by "like" I mean a good user experience where the program doesn't crash, fulfills the need that the user has and adhere's to the Principle of Least Surprise.
Note I say "more important" because code is not something the user sees or is interested in. Code quality and "beauty" is important to developers because it's what they see of the program and what they hand over to other developers.
I remember reading something some time ago comparing (in general terms) software developed for the windows platform and software developed for OS X. In general terms it said that windows programs tended to be developed by developers who didn't spend too much time on the UI or thinking about the user experience. Their concentration was getting every piece of functionality they could think of into the program without any thought about it making sense. Mac OS X on the other hand tended to be developed by people concentrating on the user experience first and solving their problems. So it didn't necessarily have as much functionality, but what it did have was directly associated with what the user needed and was easy to use.
So when is it time to stop and think about the UI? The fact that you have asked the question makes me think it's time to stop right now. If anything I'd suggest that even before writing any code you should have drawn out a basic UI and worked out what sort of user experience your program is going to provide If you cannot work that out, you don't want to wasting time writing code because you will never use it.
Thats not to say I think code "beauty" is irrelevant. I spend time on making sure my code is well written, easy to follow and looks "good". But that's after I've figured out the UI and because I've had a lot of experience with cleaning up other people aweful code :-)
This is an incredibly broad question, and the answer is entirely a function of what you're building, why, and for whom.
Some random bits of conventional wisdom that I agree with:
If you're building broadly-applicable consumer software (e.g. for Mac or iOS), then the UI is a critical component of the application. Spend lots of time on it. :) Work with designers. If your software looks like crap, no one will want to use it. (Assuming nobody's going to make them: see next point.)
If you're building internal or enterprise tools, UI polish is probably less important.
Even if you're a one-man (or woman) operation, think of engineering as distinct from "product management". Product management is the thought process that determines what the software should do, and how it should work (and look). Engineering creates the reality, but has different tradeoffs. These are sometimes in conflict, which is hard to handle if you're one person, but try to wear different hats.
In all cases, your code should work, for some reasonable definition of work.
If it's ugly because it's hacked together, you're likely to run into accuracy/correctness problems sooner than if you construct it methodically. It will also be harder to maintain. The tradeoff here is almost never worth it. As you gain experience, you'll more naturally write clean code from the start, even if it's "scratch" code. You'll save time in the long run this way, and not be faced with later wholesale attempts to improve its beauty.
If you're on a team, or working with others, clean code is even more important. Find out if there are any "local" coding conventions, and work closely with colleagues.
As far as improving "how code runs", if you mean performance optimization, don't do any of that until you're sure you need to. Write the simpler code first, even if it's slower. It's likely that it won't be slow enough to matter.
Special case: if you're writing a game, long-term maintainability is less important, because they tend to be "throwaway" at some level. YMMV.

How important is managing memory in Objective-C?

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

Is garbage collection used in production quality Cocoa apps?

I'm mainly wondering about the affect that garbage collection would have on performance. Is the use of garbage collection frowned upon for release apps?
Another concern that I can think of is that using garbage collection could lead to sloppier programming.
Do you use garbage collection in your apps?
Garbage Collection is used in many production quality applications. Xcode, Automator, System Preferences and several other system applications are GC'd, and you can expect that trend to continue over time.
As well, many developers have embraced GC and are using it exclusively in their applications. Intuit's new versions of Quicken and QuickBooks for the Mac are garbage collected, for example.
There are a number of advantages of GC, too. Off the top of my head and from personal experience:
it makes multithreading easier; a simple assign is an atomic declaration of ownership
it offloads a bunch of memory management to other cores; it is naturally concurrent and offloads a bunch computation from the main thread (or computation threads)
in many cases, allocation and deallocation can happen entirely within the context of a thread, thus eliminating any need for global synchronization or locking
the collector has gotten faster with each release of Mac OS X and that trend will continue (just as it has with the rest of the system). By offloading more of your app's computational load to the system provided frameworks, your app will gain more and more from optimizations to the underlying system.
because the collector has intimate knowledge of the object graph -- of the pointers between objects -- in memory, it makes analysis and debugging significantly easier. Instead of "where did this dangling pointer come from?", the question is now "Give me a list of reasons why this object is sticking around longer than I think it should?".
This isn't to say that there isn't work to do to make your application work optimally under GC. There certainly are such tasks!
Garbage collection has been around since the 1960s and is used in many released applications. All .NET apps use garbage collection. Apple uses libauto in Xcode.
Garbage collection generally leads to better quality apps in Cocoa since the developer is freed from the memory management burden. There are tons of Cocoa apps that leak! (though it may not a significant amount of memory)
I tend to use gc since since I can turn around my apps faster and don't have to worry about messaging zombie objects!
I use GC whenever I can, because the best code of all is the code you don't have to write in the first place. Also, as Bbum pointed out above, running under GC means that you have far more information available for performance analysis, should you need to debug any bottlenecks.
Garbage collection is recommended for any new Cocoa applications, and Apple eats its own dog food by using it in Xcode. Performance is an interesting situation, because while you're most likely going to be consuming more CPU cycles overall, the application may actually end up faster in some areas due to multithreading of the collector and the simplification of accessor methods.
Computers are made to do work for us. Cocoa's reference counting is usually easy to manage, but garbage collection is one more thing it can do now--let the machine do the work so you can focus on things that matter!
Like the others, I would strongly recommend using GC. The performance overhead usually is negligible! I don't need to repeat the benefits as stated by other users.
However, I would strongly encourage writing libraries, as opposed to applications, to run in a non-GC mode as well. Some environments cannot run GC code, the iPhone being the notable one; so if you created an internal library for yourself, that you envision reusing it later for an iPhone app, then I would recommend designing it so it would work in a non-GC environment as well.
Converting a GC code to non-GC code is much more difficult than the other way around!