Improving iOS Performance

There are some points to consider when improving iOS Performance:

1. Reuse identifiers:

When you are working with Cells, is important to set an identifier, because when dequeues an existing cell, the method dequeueReusableCellWithIdentifier use a existing cell if is available or creates a new one if necessary using the previously registered.

2. Reuse expensive objects:

Some objects are very slow to initialize — NSDateFormatter and NSCalendar are two examples. To avoid performance bottlenecks when working with these objects, try to reuse these objects if at all possible. You can do this by either adding a property to your class, or by creating a static variable.

3. Fat Xibs vs StoryBoards:

When you are working with XIB, remember that when you load a XIB into memory, all of its contents are loaded into memory, including any images. If you have a view you’re not using immediately, then you’re wasting memory. It’s worth noting that this won’t happen with storyboards, since a storyboard will only instantiate a view controller when it’s needed. So, be careful with Fat Xibs!

4. Views:

4.1 Opaque property. Views that have no transparency defined — you should set their opaque property to YES. Possible mistake here when the designer changes one image with transparency, you set the opaque property to NO. Everything okai, but imagine that the designer changes the image with no transparency. You replace the image and it's easy to forget to set back the opaque property to YES. Be careful about this!

4.2 Lazy Loading. Another point with the Views, is to use the technique of Lazy Loading. For example, working with images in TableViewCells. There are a library called SDWebImage to deal with that:

[cell.imageView setImageWithURL:(NSURL *) placeholderImage:(UIImage *)]

5. Images:

5.1 Image Optimization Working with heavy images allways is a problem. Optimize the images that you use in the APP. You can use a program like ImageOptim to deal with that.

5.2 Use Sprite Sheets. Sprite sheets make drawing faster and can even consume less memory than standard screen drawing methods.

5.3 Set Background Images Appropriately

UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background"]];
[self.view addSubview:backgroundView];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background"]];

If you have a full size background image, then you should definitely use a UIImageView because UIColor’s colorWithPatternImage was made to create small pattern images that will be repeated, and not large images size. However, if you plan to have a patterned image background, which uses smaller images which will be repeated or tiled to fill the background, you should go with UIColor’s colorWithPatternImage instead, as it’s faster to draw and won’t use a lot of memory in this case.

5.4 Don’t Block the Main Thread. If you have to display a heavy image, use GCD

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // switch to a background thread and perform your expensive operation
    dispatch_async(dispatch_get_main_queue(), ^{
        // switch back to the main thread to update your UI
        NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:kImageURL];
        UIImage* image = [[UIImage alloc] initWithData:imageData];
        self.imageView.image = image;
    });
});

6. Correct Data Objects:

6.1 JSON vs XML. There are multiple ways you can transfer data to your app from a web service, but the most common two are JSON and XML. You want to make sure you choose the right one for your app. You should take a look at this Funny Video talking about an API SOAP returning a JSON into an XML response. LOL

6.2 NSUserDefaults vs Save Local File vs CoreData. NSUserDefaults is for save small data, if you have to save large data, better options could be to save a local file or use CoreData. Also remember that saving a file can be problematic as well. Generally, you need to load the entire file into memory before you can parse it, which is an expensive operation. The best choice is CoreData or, do you know Realm? Take it a look!

6.3 Choose the Correct Collection. Most common collection types are Array, Dictionaries and Sets. An Array is an ordered list of values. Quick lookup by index, slow to lookup by value, slow to insert/delete. A Dictionary store key/value pairs. Quick lookups by key. A Set is an unordered list of values. Quick lookup by value, quick to insert/delete. Think before using a collection to choose the correct one!

7. Cache:

7.1 Cache what matters. A great rule of thumb when developing your app is to “cache what matters” — that is, things that are unlikely to change, but are accessed frequently. What can you cache? Some candidates for caching are remote server responses, images, or even calculated values, such as UITableView row heights.

7.2 Cache image or not?

UIImage *img = [UIImage imageNamed:@"myImage"]; // caching
// or
UIImage *img = [UIImage imageWithContentsOfFile:@"myImage"]; // no caching
If you’re loading a large image that will be used only once, there’s no need to cache the image. In this case imageWithContentsOfFile will fit the bill nicely.

7.3 Autorelease Pool. Create temporary objects into @autoreleasepool block.

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}
This releases all the autorelease objects at the end of each iteration.

8. Memory Leaks:

It’s very important to release all memory possible once you receive a memory warning. Otherwise, you run the risk of having your app killed by the system. You can use Instruments to deal with it!

For more information about improving iOS Performance, take a look at this post in RayWenderlich which this article is inspired with and some content is directly copied from it.