Sunday, 28 May 2017

Uses of Block in Objective C

Block is same as the c function.The basic idea of a block is to treat a small piece of code as if it were a value. The piece of code can then be passed as a parameter in messages or assigned to a variable. 

With the help of block it's very easy  to write code which is simple , easy to debug, readable and maintainable. So let's have a look at the syntax and see how it works:


^{NSLog(@"This is a block"); }


A block is the only object that begins its life in stack, rather than heap memory.A very effective use of a block literal is to deal with a callback. 

Creating a block variable:

int  (^sum)(int, int) = ^(int a , int b){
 return a+b;
}

This  is a simple block definition . It takes two parameters  of type int and return one int parameter.
To call this block as:

int c = sum(3,5);
NSLog(@"sum is %d",c);

When a block is created, it will capture, or close around, the values of those variables that the code has referred to and that are in the same lexical scope of the block. Essentially, a snapshot is taken of these values. These values are preserved in the memory allocated for the block and cannot later be changed. It is said that these variables are "captured by value".
To change the this behavior(to use the latest values of the variable), we can declare these variable as 
__block storage specifier.

__block int z =5;

Block as method parameter: We can also use block as method parameter to use call back. For example:

-(void)validateString:(NSString *)str onCompletion:(void(^)(bool isValidate))completion{
          
 if(str.length ==0){
    completion(NO); //call block
}else{
    completion(YES);
}
}

Now call this method as 

[self validateString:@"demoiOS" onCompletion:^(bool isValidate){
    
if(isValidate){
 //str is valid, handle it
}else{
  // str is not valid, handle it here
}       
   
}];


Thursday, 11 May 2017

Closure Capture list

In Swift, closures are reference type means they reference to objects and properties which comes in the defined context of the closure. What it's means? To understand this concept, let's have a look on  this example:

var a = 23
var b = 35


Note: I am not digging in the deep about what is closure and how it work. I assume you already know the basics of the closure. By definition closure is an object like other objects in Swift which can be stored, referenced and passed as a argument to the functions .

Now create a closure which will print the value of these two variable.

var myClosure: () -> ()  = { print("a = \(a) and b = \(b)") }


Here we define  a closure and stored it in a myClosoure . We can call a closure like any other function s in Swift as:

myClosure()

This will print the value of a and b   as:

a = 23 and b = 35

Now try to change the value of  a and b and then call the  closure 

a = 45
b = 55
myClosure()

The output will be 

a = 45 and b = 55

What is this? It means closure captures the latest value  of the properties and object which comes in the defined context of the  closure. 

Now we have idea of how closure is reference type.  A closure in Swift keeps the reference to the properties , it doesn't copy them by default. But we can changes this default behavior  of the closure means in Swift it's possible to allow closure to copy the value of properties and objects in the defined context of the object. The rescue is called Capture List .

To allow a closure to copy the properties of the object we pass these value in an array which is called Capture List. 

To copy the value we add these value in an array and place this array before in keyword in a closure.

Now edit the above defined closure in order to copy the value of the properties like this:

var a = 23
var b = 35

let  myCopyClosure:() -> () = { [a ,b] in 
              print("a = \(a) and b = \(b)") 
               }

//call the closure
myCopyClosure()

This will print the value as earlier:

a = 23 and b = 35

Try to change the value and then call the closure 

a = 45
b = 55
myCopyClosure()

Now the output will be

a = 23 and b = 35


Did you see the difference?  This time closure copy the value of properties which are added in the capture list of the closure. The closure copy the value of  a property , it's have at the time when we defined the closure. Now it's doesn't matter how many time we change the value of a  and b .

Reference: Official document of Swift from Apple

Sunday, 7 May 2017

Working with Optional Chaining in Swift

Optional chaining is process for querying and calling properties, methods, and  subscripts on an optional that might  be currently nil. If the optional contains a value then call to properties, methods or subscript will success otherwise call will return nil if any optional is nil in the calling chain.

Optional chaining is alternative to forced unwrapping.  In forced unwrapping we place an exclamation mark(!) after the optional value to force the unwrap of its value.

But in optional chaining we put the question mark(?) after the optional value . The main difference between forced unwrapping an optional chaining is that  in forced unwrapping if optional doesn't have a value then we get a run time error. But in optional chaining if optional doesn't have value means it's nil then it gracefully returns nil?.(optional nil).

A point to remember about optional chaining is that if we are accessing properties, calling methods or accessing subscripts , they all return nil? if optional chaining fails at any levels.

 The result of optional chaining call is of the same type as the expected return value, but wrapped in an optional.

Example :

     class MyClass{

     var  address:Address?
}

class Address{

  var streetName =  "12A Arthur Road"
}


let myClass  =  MyClass()

First we are accessing the  with forced unwrapping:

let address = myClass.address!.streetName

This call will give a run time error because currently the value of address is nil in MyClass.

Now with optional chaining :
 let address = myClass.address?.streetName

This call will end gracefully because with optional chaining if it fails at any level it returns nil. It is same as calling nil in objective C.