iDev: Guidelines for iOS Developer

images (2)

Here the some concern, which is always in your mind as a developer:

Apple’s iPhone – Memory Constraints

The most visible aspect for any mobile application, other than its look and feel, is the speed in terms of user interface’s responsiveness. This performance may be impacted not only by hardware constraints like processing power or available memory but also due to network delays while pulling data. Apple’s iPhone provides 128MB of RAM (iOS5 have a quad-core chip with 1 GB of RAM ), part of which is dedicated for user interface only. Even though only one user application is running at a time, still there are a bunch of applications (like mail, clock, push, music) that are running in the background consuming additional memory. Your application must be able to run under the presumption of low memory and the fact that an incoming phone call or text message will further decrease the available memory, potentially resulting in a memory warning to your application. The application will get terminated if you don’t release memory when you get these memory warnings. Ideally, your application should stay within 7-8Mb limit to successfully overcome any memory issues. Apple’s development environment comes with tools that let you gauge the memory footprint as you move through your application.

Memory Management – Objective-C

Memory management is core to any programming language, and it is always easier when you need not worry about it, like in Java or SmallTalk. But the ability to manage your own memory is a powerful aspect of Objective-C programming. When used correctly, Objective-C’s memory management using the retain/releases commands runs smoother and faster than Java’s garbage collection although it does place a much larger burden on the developer and introduces a much larger risk of memory leaks. As long as you strictly follow the simple rule, ‘You must take responsibility for releasing (i.e. de-allocating) any object that you have allocated or retained’, memory handling should be fine in Objective-C. Some background in handling memory elsewhere (like using malloc/free in C) can help expedite your learning but be aware of some interesting Objective-C specific syntax and concepts (read here).

How it works

Objective-C uses a retain/release mechanism, along with autorelease pools which provide a degree of automated memory management. It is much more elegant than C’s malloc/free (or C++’s new/delete), and provides much better control over memory management as compared to Java’s automated garbage collection. Unlike Java, where you are free to create as many objects, simply drop references when done and garbage collection will eventually notice the need to cleanup, Objective-C is stricter about managing memory. When an object is created, it has a retain count of 1. When an object is retained, the retain count is incremented and similarly when it is released the retain count is decremented. When the retain count goes to zero, the object will call [self dealloc], thereby releasing the object’s memory. This provides the developer with much more control over when the object’s physical memory is actually released.

The default convention about using the ‘retain’ and ‘release’ is that any block of code that causes an object to be allocated, ‘owns’ this object and is responsible for releasing it. More generally, the total number of ‘retain’ in a block should be matched by an equal number of ‘release’.

Cocoa library (collection of frameworks, APIs and Runtime) defines a NSObjectclass, which is the root of most Objective-C class hierarchies. NSObject implements a semi-automated reference counting version of garbage collection and other objects inherit a basic interface to the runtime system through NSObject. This interface provides procedures (listed below) for managing an object’s Retain Count and understanding the way they work are crucial to making sure your application uses proper memory management.

NSObject provides the following messages to manage objects:

  1. 1.     alloc: Creates new object by allocating physical memory and setting the reference count to 1. When done with this object, there must be a corresponding release.
  2. 2.     init: Simply initializes the object. It may be used along with ‘alloc’ and does not impact the reference count by itself. If you override init, it must always return itself (id).
  3. 3.     dealloc: Frees the memory obtained by alloc. Instead of calling dealloc directly on an object, call release – let the memory manager perform dealloc, when appropriate (i.e. if retain count becomes zero).
  4. 4.     retain: Signals that we are interested in this object causing the retain count to be incremented by one.
  5. release: Signals that we are no longer interested in this object causing the retain count to be decremented by one.

Note that if you decide to override any of these methods, be sure to call super’s corresponding method at the appropriate time.

Autorelease Pools

Autorelease pools (supported by NSAutoReleasePool class) are an important aspect of Cocoa’s memory management system that helps in lowering the overhead of dealing with retain/release semantic. An autorelease pool acts like a simple list containing objects that are to be released when the pool itself is deallocated. The AppKit (set of classes primarily dealing with user interface elements for developing applications) usually ensures that you always have an autorelease pool. You may create your own autorelease pools (they are stackable) specially when your application creates a lot of temporary autoreleased objects within a event loop in order to minimize the peak memory footprint as shown in the example below,

-(void) someFunctionDeclaration {

for(int i=0; i<100; i++) {

// create your oqn autorelease pool

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// these objects get added to the autorelease pool you created above

NSNumber *aNumber = [NSNumber numberWithFloat:1];

NSString *aString = [NSNumber stringWithFormat:@”Temporary String Data”];

NSNumber *anotherNumber = [NSNumber numberWithFormat:N];

// … do some processing with objects created above.

[pool release]; // all objects added to this pool are released

}

}

When you send an ‘autorelease’ message to an object, that object will be added to the most recently created (on the current thread) pool’s list of items to release. Once that pool is itself released (or drained), it will send a ‘release’ message to all objects that were added to that autorelease pool, decrementing their retain count and the object may be deallocated if the retain count becomes zero. Thus, sending autorelease instead of release to an object extends the lifetime of that object at least until the pool itself is drained (it may be longer if the object is subsequently retained).

Autorelease pools are specifically useful when you don’t know how long you need an object reference, for instance when you return an object. In such scenario, you can’t send a release message to the object within the method that created it, but not releasing that object will lead to a memory leak. By sending the object an ‘autorelease’ message, it gets added to the local autorelease pool and may be further retained by the calling function, if needed. In general, all objects returned from functions (other than alloc/copy) should be considered to be autoreleased.

Handling Memory Warnings

Given low available working memory amid background applications and unpredictable user behavior, it is ofter better to sacrifice the snappy user interface for a low memory footprint and avoid any application crashes. It is recommended to delay loading all resources until they are needed. If one NIB contains a lot of views, it is better to create multiple NIBs files so as to load the NIB individually when needed.

Before an out-of-memory crash, a ‘didReceiveMemoryWarning’ message is sent to your view controllers. The purpose of ‘didReceiveMemoryWarning’ is to give you a chance to free memory or pop views to avoid a crash. It is highly recommended that you override this message in all your view controllers and handle the warning properly and free up memory, then you can avoid an application crash. Also, when ‘didReceiveMemoryWarning’ message is called, the setView message will also be called with a nil parameter. It will be called to release the view if the view is not the active view. This is where you will want to release as much resources as you can, such as all your IBOutlet variables. Also, do not forget to call the corresponding parent methods or your application will crash.

Static Code Analyzer

In addition to code reviews and careful coding practices, a static code analyzer can save many a headaches and help in discovering potential vulnerabilities. We used‘clang’ for our project that helped identifying some not so serious and also a few potentially serious bugs based on the memory footprint. We found this tool to be easy to setup with configurations that allow it to be run locally on developer’s machine or along with the build to generate reports with filenames and line numbers for easy discovery and correction.

Apple’s IDE – XCode

Apple’s IDE tool XCode is tightly integrated with Cocoa framework and includes powerful optimization and analysis tools called Instruments. Instruments collects data such as disk, memory, or CPU usage in real time on your connected iPhone that can help you track down performance bottlenecks in your applications. You can dynamically view the leaks as well as memory object allocation along with exact location in your code.

General Tips

– NSObject provides a method called retainCount that you may use to get an object’s current retain count. This can be very handy for debugging purposes as, NSLog([NSString stringWithFormat:@”Retain Count:%i”, [yourObject retainCount]]);

– You should override the ‘dealloc’ method in your classes to release any memory that you may have allocated (make sure to super’s dealloc)

– In setters methods, always retain the new object first, and then release the old object. This will take care of scenarios when same value is being set.

– When you add an object to a collection such as an array, dictionary, or set, the collection takes ownership of it. The collection will relinquish ownership when the object is removed from the collection or when the collection is itself released.

– When your view is freed while handling ‘didReceiveMemoryWarning’, the NIB will be read back into memory when it is needed the next time. This will cause ‘viewDidLoad’ message to be called again. So make sure you have the appropriate initialization code in that message.

– XCode’s Instruments allows you to manually trigger a memory warning that can be very helpful in flushing out memory warning issues.

– If you are making Cocoa calls outside of the Application Kit’s main thread—for example if you create a Foundation-only application or if you detach a thread—you need to create your own autorelease pool.

– You should always drain an autorelease pool in the same context (invocation of a method or function, or body of a loop) that it was created.

Here some tips:

For Naming convention Standard please read this link :

  1. CodingGuidelines
  2. NamingConventions

 

For UI Design Specification Standard

  1. Human Interface Guidelines

Every time, when you finished some task you must check  this:

  1. Warnings (Remove all Warning in the code).
  2. Analyze tools used (Xcode 4.5 & above) → remove all potential leaks , read this for run Analyze in your project :
  3. How to analyze

After completing these two steps you must check run time leaks and optimization the code, way are:

Run the Instruments on the Simulator first and test , and check the allocation and leaks, then optimized the code and remove the leaks.

For the memory management you can referred the following link:

Memory Management Tips

Managing Memory Help

How to design and memory analyse

For the Instrument Run technique you can referred the following link :

Xcode- Instrument Guide,

Finding Leaks

How to debug and finding memory leaks

For ARC enabled Architecture : Handled Memory Management referred following link :

images (1)

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s