Performance is an important factor in all software products. If a program runs slowly or displays a spinning cursor, user would get frustrated with the program and look for the alternatives.

When developing an iOS app, it’s critical that your app has good performance. Your users expect it, and it will hurt your reviews if your app appears unresponsive or slow.

The following sections describe the factors you should consider throughout the development process.

 Coding Performance Tips & Tricks

ARC stands for “Automatic Reference Counting”, and it automatically manages the retain/release cycles in your code, so you don’t have to do it manually.

ARC is used to avoid memory leaks.ARC can also improve app’s performance, by making sure that objects are deallocated as soon as they are no longer needed.

The NSPredicate class is used to define logical conditions used to constrain a search either for a fetch or for in-memory filtering.

We use predicates to represent logical conditions, used for describing objects in persistent stores and in-memory filtering of objects. Although it is common to create predicates directly from instances of NSComparisonPredicate, NSCompoundPredicate, and NSExpression, you often create predicates from a format string which is parsed by the class methods on NSPredicate.

In IOS development we use predication in following scenarios

1) Using NSPredicate with Core Data

2) Using NSPredicate with Collections(Array, Dictionary and Set)

Reference Link

  • Notification for Broadcasting scenario

An NSNotificationCenter object (or simply, notification center) provides a mechanism for broadcasting information within a program. An NSNotificationCenter object is essentially a notification dispatch table.

Objects register with a notification center to receive notifications (NSNotification objects) using the addObserver:selector:name:object: or addObserverForName:object:queue:usingBlock: methods. Each invocation of this method specifies a set of notifications. Therefore, objects may register as observers of different notification sets by calling these methods several times.

Reference Link

While dealing with UICollectionview and UITableView most of the developer is not setting the correct reuseIdentifier or not reuse the Cells,due to which application’s performance decreases.

To use reuse Identifiers, call this method from your data source object when asked to provide a new cell for the table view:

Objective C

 static NSString *CellIdentifier = @"Cell";  
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];  

Swift

  let cell = tableView.dequeueReusableCell(withIdentifier: “Cell”, for: indexPath) as! UITableViewCell  

1

This method dequeues an existing cell if one is available, or creates a new one if necessary using the previously registered nib file or class. If no cell is available for reuse, and you did not register a class or nib file, this method returns nil.

When you load a Storyboard 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 precious 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 Try to add content which actual required while loading the UIView inside memory.
When you load a nib file that contains references to image or sound resources, the nib-loading code reads the actual image or sound file into memory and caches it.So Always try to use imageNamed: method of UIImage class for loading image.

2

You should never do any heavy lifting on the main thread. This is because UIKit does all of its own work on the main thread, such as drawing, managing touches, and responding to input.

The risk of doing all of your app’s work on the main thread is that if your code does block this thread, your app will appear unresponsive.

Most cases of blocking the main thread occur when your app is performing an I/O operation which involves any task that needs to read or write from an external source, such as the disk or the network.

Try to use NSOperationQueue and GCD for performing a time-intensive computation or reading/writing to the disk.

Objective C

 UIImageView *imageView;  
 //created background Queue and set default property for opration  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    //download image data from URL  
    NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@”yourURL”]];  
    UIImage *image=[UIImage imageWithData:data];  
    dispatch_async(dispatch_get_main_queue(), ^{  
       // switch back to the main thread to update your UI  
       imageView.image=image;  
    });  
 });  

Swift

 let imageView;  
 //created background Queue and set default property for opration  
 DispatchQueue.global().async {
            guard let fileURL = fileURL else {
                return
            }
            do {
                let data = try Data(contentsOf: fileURL)
                if data.count > 0 {
                    let image = UIImage(data: data)
                    DispatchQueue.main.async {
                      imageView.image = image
                    }
                }
                } catch {
             }
        }  

Following are few types of collection .Developer need to choose the respective type as per requirements

Arrays: Ordered list of values. Quick lookup by index, slow to lookup by value, slow to insert/delete.

Dictionaries: Store key/value pairs. Quick lookups by key.

Sets: Unordered list of values. Quick lookup by value, quick to insert/delete.

For Customizing button or any layout we can prefer to use Images , but some case it increases the application’s resource size, So to achieve customization of image we can use CALayer, Core Graphics or even OpenGL. But while using this manual customization, we have to take care of memory allocation of the device. So we have to use memory wisely and perform operations on GPU.

3

Reference Link

iOS notifies all running apps when system memory is running low.If your app receives this warning, it must free up as much memory as possible. The best way to do this is to remove strong references to caches, image objects, and other data objects that can be recreated later.

Fortunately, UIKit provides several ways to receive these low-memory warnings, including the following:

Implement the applicationDidReceiveMemoryWarning: method of your app delegate.

Override didReceiveMemoryWarning in your custom UIViewController subclass.

Register to receive the UIApplicationDidReceiveMemoryWarningNotification notification.

Some objects are very slow to initialize — NSDateFormatter and NSCalendar are two examples. However, you can’t always avoid using them, such as when parsing dates from a JSON/XML response.

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.

The code below demonstrates how to create the NSDateFormatter Singleton instance inside the application

Objective C

 – (NSDateFormatter *)formatter {  
     static NSDateFormatter *formatter;  
     static dispatch_once_t onceToken;  
     dispatch_once(&onceToken, ^{  
       _formatter = [[NSDateFormatter alloc] init];  
       _formatter.dateFormat = @”EEE MMM dd HH:mm:ss Z yyyy”; // twitter date format  
     });  
 return formatter;  
 }  

Swift

 static let dateFormator = DateFormatter()
    static func formatDate(format:String, date:Date)->String {
        dateFormator.dateFormat = format
        return dateFormator.string(from: date)
    }

Launching your app quickly is very important, especially when the user launches for the first time. First impressions mean a lot for an app!

The biggest thing that you can do to ensure your app starts as quickly as possible is to perform as many asynchronous tasks as possible, such as network requests, database access, or parsing data.

As well, try to avoid fat XIBs, since they’re loaded on the main thread. But recall that storyboards don’t have this problem — so use them if you can!

NSAutoreleasePool is responsible for releasing the autoreleased objects within a block. Usually, it’s called automatically by UIKit. But there are some scenarios where may you need to create NSAutoreleasePool manually.

For example, if you create a lot of temporary objects in your code, you’ll note that memory usage increases until these objects are released. The problem is that this memory is only released after UIKit drains its autorelease pool, which means this memory is held much longer than necessary.

Objective C

 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. */  
    }  
 }  

Swift

 NSArray *urls = <# An array of file URLs #>;  
 let urls = [URL]()
        for url  in urls {
            autoreleasepool {
                do {
                    let data = try Data(contentsOf: url)
                }catch {
                }
             }
        }

This releases all the autorelease objects at the end of each iteration.

You can read more about NSAutoreleasePool in Apple’s official documentation.

  • Lazy loading Concept

While dealing with mobile application , to download image from url and rendered it in iPhone application ,is very critical process and resource consuming(cellular data,battery,CPU and device memory),So in order to minimize this, the caching model is come into front.

To achieve a great user experience, it’s important to understand the IOS hood when we cache and load the images.

What is Lazy loading

It is used to download images.So that application does not freeze up while images are being downloaded.

If an iOS application fetches a remote resource, it is important that it doesn’t fetch that same resources every time it needs to access it. If you plan to develop a Twitter client for iOS, for example, then the client shouldn’t be downloading the same avatar every time it needs to display it. Caching the avatar will significantly improve application performance.

What is caching?

The basic idea of caching is simple. When the application fetches a remote resource for the first time, it stores a copy of that resource on disk for later use. If that same resource is needed later, the application can load it from disk instead of fetching it remotely. The added benefit is that the resource is also available when the device is not connected to the web. The complex aspect of caching is how to store the resource, when to store it, and, most importantly, when to refresh it.

Following are the image caching SDK

1)Kingfisher :- https://github.com/onevcat/Kingfisher

2)Alamofire :-  https://github.com/Alamofire/Alamofire

3) SDWebImage :-https://github.com/rs/SDWebImage

4)AFNetworking :-https://github.com/AFNetworking/AFNetworking

5)Fast Image cache.https://github.com/path/FastImageCache

6)Async ImageView:-https://github.com/nicklockwood/AsyncImageView

Using this library we can easily manage the image loading inside TableView ,Scrollview, WebView and CollectionView.

  • Concurrency Programming

Concurrency programming is the process in which multiple task is performed in same time.Concurrency describes the concept of running several tasks at the same time. This can either happen in a time-shared manner on a single CPU core, or truly in parallel if multiple CPU cores are available.

Objectives of Concurrency

Running program in background without hogging CPU.
Define Tasks, Define Rules and let the system take the responsibility of performing them.Improve responsiveness by ensuring that the main thread is free to respond to user events.
Leverage more cores to do more work in the same amount of time.

NSOperationQueue

NSOperationQueue regulates the concurrent execution of operations. It acts as a priority queue, such that operations are executed in a roughly First-In-First-Out manner,with higher-priority (NSOperation.queue Priority) ones getting to jump ahead of lower-priority ones.

Operations and Operation Queue

Object oriented way to encapsulate work that needs to be performed asynchronously,An Operation object is an instance of NSOperation(abstract) class.NSOperation class has two concrete subclasses that can be used as is

1)NSInvocationOperation (used to execute a method)

2)NSBlockOperation (used for executing one or more blocks concurrently)

An operation can be executed individually/manually by calling its start method or it can be added to an Operation Queue.

Dispatch Queue(GCD):-

Grand central dispatch – dispatch queues allows us to execute arbitrary blocks of code either asynchronously or synchronously,All Dispatch Queues are first in – first out.All the tasks added to dispatch queue are started in the order they were added to the dispatch queue.

Dispatch Queue Types

1)Serial (also known as private dispatch queue)

2)Concurrent

3)Main Dispatch Queue

When to Use NSOperation

NSOperation can be scheduled with a set of dependencies at a particular queue priority and quality of service. Unlike a block scheduled on a GCD queue, an NSOperation can be cancelled and have its operational state queried. And by subclassing, NSOperation can associate the result of its work on itself for future reference.

Just remember: NSOperation and Grand Central Dispatch are not mutually exclusive. Creative and effective use of both are key to developing robust and performant iOS or OS X applications.

When to Use Grand Central Dispatch

Dispatch queues, groups, semaphores, sources, and barriers comprise an essential set of concurrency primitives, on top of which all of the system frameworks are built.

For one-off computation, or simply speeding up an existing method, it will often be more convenient to use a lightweight GCD dispatch than employ NSOperation.

Please find below link for more reference

http://www.knowstack.com/concurrency-nsoperationqueue-grand-central-dispatch/

http://nshipster.com/nsoperation/

  • Reduce Your App’s Power Consumption

Power usage and memory consumption are extremely important considerations for iOS apps, and there are many other considerations as well.Power consumption on mobile devices is always an issue. The power management system in iOS conserves power by shutting down any hardware features that are not currently being used.You can help improve battery life by optimizing your use of the following features:

1) The CPU
2) Wi-Fi, Bluetooth, and baseband (EDGE, 3G) radios
3) The Core Location framework
4) The accelerometers
5) The disk

Following are few points which we have to take care while performing task

Avoid doing work that requires polling. Polling prevents the CPU from going to sleep. Instead of polling, use the NSRunLoop or NSTimer classes to schedule work as needed.

Leave the idleTimerDisabled property of the shared UIApplication object set to NO whenever possible. The idle timer turns off the device’s screen after a specified period of inactivity. If your app does not need the screen to stay on, let the system turn it off

Do not draw to the screen faster than is needed. Drawing is an expensive operation when it comes to power. Do not rely on the hardware to throttle your frame rates. Draw only as many frames as your app actually needs.

Connect to external network servers only when needed, and do not poll those servers.

If you use the Core Location framework to gather location data, disable location updates as soon as you can and set the distance filter and accuracy levels to appropriate values. Core Location uses the available GPS, cell, and Wi-Fi networks to determine the user’s location. Although Core Location works hard to minimize the use of these radios, setting the accuracy and filter values gives Core Location the option to turn off hardware altogether in situations where it is not needed.

If you use the UIAccelerometer class to receive regular accelerometer events, disable the delivery of those events when you do not need them.

Credits

http://www.raywenderlich.com

http://www.raywenderlich.com/31166/25-ios-app-performance-tips-tricks