Friday, 30 October 2015

NSOperationQueue and NSOperation

GCD is a lightweight way to represent units of work that are going to be executed concurrently. You don’t schedule these units of work; the system takes care of scheduling for you. Adding dependency among blocks can be a headache. Canceling or suspending a block creates extra work for you as a developer! .

NSOperationQueue and NSOperation add a little extra overhead compared to GCD, but you can add dependency among various operations. You can re-use operations, cancel or suspend them. NSOperation is compatible with Key-Value Observation(KVO) .

NSOperationQueue regulates the execution of a set of NSOperation objects . After being added to queue an operation remains in the queue until it is explicitly  canceled or finishes it  executing its task .
We can add inter operation dependencies among operations  which provide absolute execution order for operations even if  those operation located in different operations queues .
An operation object is not considered ready to execute until all of its dependent operation have finished executing .
Operations are always executed on a separate thread, regardless of  whether they are designated as asynchronous or synchronous .

NSOperation is an abstract class we use to encapsulate the code and data associated with a single task . We subclass it or use one of the system defined subclasses (NSInvocationOperation or NSBlockOperation) to perform actual task.
An operation executes its task once and can't be used to execute again .

To create a customize operation , follow these steps : 
1) Subclass NSOperation .
2) Override main .
3) Create an autoreleasepool in  main .
4) Put your code in autoreleasepool .

The reason we should create our own autorelease pool is that we do not have access to the autorelease pool of the main thread, so we should create your own.

example:
#import <Foundation/Foundation.h>

@interface MyOperation: Operation
@end

@implementation MyOperation

-(void)main{
      @autoreleasepool{
       //define task here
       NSLog(@"custom operation");
      }
}
}
@end

NSOperationQueue API:
1) To get a queue use:
   NSOperationQueue *myQueue = [NSOperationQueue alloc]init];
   myQueue.name = @"queueName";

2) Maximum number of concurrent operations: To set maximum number of operations that  NSOperationQueue can run concurrently .
   myQueue.MaxConcurrentOperationCount = 2;

3) To add operation to queue :
   [myQueue  addOperation:customOperation] ;

4) To pause a queue :
  [myQueue setSuspended:YES];

   To resume , set the setSuspended to NO .
5) To cancel operation in a queue:
   [myQueue cancelAllOperations];

NSOperation API:

1) To make an operation dependent on other operation:

   lets assume op1 and op2 are two custom operation object .
 [op2 addDependency op1];

2) To set the priority of the operation :

[op1 setQueuePriority:NSOperationQueuePriorityVeryLow];

3) To set completionBlock :

[op1 setCompletionBlock: ^{
   NSLog(@"operation has completed).
}];
 

Friday, 16 October 2015

Key Value Coding and Key Value Observer

Key-value coding is a mechanism for accessing an object’s properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables.
Key-value observer is a  mechanism for observing the changes in the property of an object .

To understand these concepts properly let do some code:

1) start a new singleView iOS project and create a new class named Person .
2) In Person.h define some properties as:

@property (nonatomic, strong) NSString *name;
@property (nonatomic) NSUInteger age;
@property(nonatomic,strong) Person * person;

3)Now initialize  these property with initial values in Person.m

4) In ViewController.m , define private properties as :

@interface ViewController ()
@property(nonatomic,strong) Person * person1;
@property(nonatomic,strong) Person * person2;


@end

5)In ViewDidLoad() method, initialize the person:
    self.person1 = [[Person alloc]init];
    
    [self.person1 setValue:@"Yash" forKey:@"name"];
    [self.person1 setValue:[NSNumber numberWithInteger:25] forKey:@"age"];

    self.person1.person = [[Person alloc]init];
    [self.person1 setValue:@"rajeev" forKeyPath:@"person.name"];

That's how we have set the value of the properties using KVC .


To observe the changes in properties we have to set the observer for the object for which we are observing and implement the method observingValueForKeyPath:

6)In ViewWillAppear() method add these lines:

[self.person1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
[ self.person1 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

[self.person1 setValue:@"Jeet" forKey:@"name"];
[self.person1 setValue:@"rajeev" forKey:@"name"];

Here we set the observer self(ViewController), and make some change to the name property of the Person  

7) Now implement the method that will be called as changes occurs in the Person's properties .

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    
   if ([keyPath isEqualToString:@"name"]) {
            NSLog(@"the name of person is changed");
            NSLog(@"%@",change);
        }
   if ([keyPath isEqualToString:@"age"]) {
        NSLog(@"the age of person is changed");
        NSLog(@"%@", change);
     }
}

Here we just print the change to the console . We can handle the changes as per our requirements .

    
    

    


Friday, 9 October 2015

Delegate in iOS

Delegation is a simple and powerful pattern in which one object in an app acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time, the delegating object sends a message to the delegate. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance (or state) of itself or of other objects in the app, and in some cases it will return a value that affects how an impending event is handled.

A common design uses delegation to allow a child view controller to communicate a value (typically a user-entered value) to its parent view controller.

The idea behind delegates is that instead of class A executing some code, it tells it’s delegate to execute that code.  The delegate is tied to another class (let’s call it class B).  In order to facilitate this, class A creates something called a protocol.  This protocol has a list of methods in it (with no definition).  Class A then has an instance of the protocol as a property.  Class B has to implement the protocol defined in class A.  Lastly, when class A is created, it’s delegate property is set to class B. 

Example:
Let’s say we have two objects, Brain and Beer Bottle, Brain is the object we use to manage the entire Body application, it handles all of the important tasks such as poop, eat, drink, sleep etc. Beer Bottle is attached to body but it doesn’t know what Brain is thinking, likewise, Brain has no idea what Beer Bottle is thinking.
Brain is using Beer Bottle’s attributes to satisfy itself while it’s watching TV, but the problem is that brain is so distracted by the tv that it can’t pay attention to when beer is going to run out. This could all end in disaster, Brain needs to know when beer is empty so that it send body to the fridge and initialize another instance of Beer Bottle.


Brain can use the drink function to lower Beer Bottles liquid variable, but once liquid reaches 0, Brain needs to know about it, this is where delegates come into action, we can use a Beer Bottle Delegate. Brain can listen out for the Beer Bottle Delegate telling brain that the bottle is empty, all we need to do is simply tell Brain to listen out for Beer Bottle telling it’s delegate that is empty and Brain can react to it. This well thought out and illustrated diagram shows all of this in action:
Creating Custom Delegates: 
For example we want to send a message to application when printing job is done in order to take appropriate action based on the message.
1) interface file
#import <Foundation/Foundation.h>
@class Printer
@protocol PrinterDelegate <NSObject>
-(void) FinishPrint;
@end
@interface Printer:NSObject{
id<PrinterDelegate> delegate;
}
@property(nonatomic, strong) id<PrinterDelegate> delegate;
-(void) printData;
@end
2) Implementation File
#import Printer.h
@implementation
@synthesize delegate; 
-(id)init{  // initialization code }
-(void)printData{
// printing instruction
[delegate performSelector@selector(finishPrint)];
}
@end
3) Finally , the class that implements printerDelegate, might have its own interface like this:
#import <UIKit/UIKit.h>
#import Printer.h
@interface MyViewController : UIViewController<PrinterDelegate>
@end
Now in implementation file we must implement the finishPrint method as:
-(void)viewDidLoad{
Printer *printer = [Printer alloc]init];
printer. delegate =  self;
}
-(void)finishPrint{
NSLog(@"printing has been done successfully");
}
References:
https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/DesignPatterns.html
http://enroyed.com/ios/delegation-pattern-in-objective-c-and-writing-custom-delegates/