By A Beginner

Every Expert Was Once A Beginner

KVC in Objective-C — April 29, 2015

KVC in Objective-C

 What is KVC?

KVC- Key Value Coding in Objective-C provides a mechanism for accessing the object properties indirectly. KVC makes use of strings to identify the objects properties ,rather than using the accessor methods or accessing them directly through instance variables.

KVC is the core technology of the binding technologies used by the controller layer (MVC), also a key mechanism behind the Core Data. By using KVC we can make the application scriptable, also using the KVC methods can simplify the applications code.

What are Keys and Key Paths?

Key is a string that identifies a specific property of  an object. Typically, a key corresponds to the name of an accessor method or instance variable in the receiving object.

Eg: For a "Person Object" the keys would be firstName,lastName,emailId,address,empId. and so on..

Key Path is string of dot separated keys that is used to specify a sequence of object properties to traverse. The property of the first key in the sequence is relative to the receiver, and subsequent key is evaluated relative to the value of the previous property.

Eg: In case of the person object again the key path 'address.street' would get the value of the address property of the receiving 'person' object , and then determine the 'street' property relative to the 'address' object.

How to get attribute values using Key – Value Coding?

We can easily get the attribute values using the method, ‘valueForKey: ‘ which return the value for the specified key, relative to the receiver. If there is no accessor or instance variable for the specified key, then the receiver sends the message valueForUndefinedKey:  to itself . The default implementation of this method raises an exception NSUndefinedKeyException; The sub classes can override this behavior.

Eg: NSString *fName = [person valueForKey:@"firstName"];
Here the string fName holds the value for the property 'firstName' of the object 'person'.

How to set attribute values using Key – Value Coding?

The method setValue:forKey: sets the value of the specified key, relative to the receiver, to the provided value.If the specified key does not exist, the receiver is sent a setValue: forUndefinedKey: message. The default implementation of this method raises an NSUndefinedKeyException ; however,subclasses can override this method to handle the request in a custom manner.

The method setValue:forKeyPath: behaves in a similar fashion, but it is able to handle a key path
as well as a single key.The setValuesForKeysWithDictionary: sets the properties of the receiver with the values in the specified dictionary, using the dictionary keys to identify the properties. The default implementation invokes setValue:forKey: for each key-value pair, substituting nil for NSNull objects as required.

One additional issue that you should consider is what happens when an attempt is made to set a non-object property to a nil value. In this case, the receiver sends itself a setNilValueForKey: message. The default implementation of setNilValueForKey: raises an NSInvalidArgumentException . Your application can override this method to substitute a default value or a marker value, and then invoke setValue:forKey: with the new value

Get Sample XCode Project showing use of KVC Here!

To know more on KVC refer:

1.Key Value Coding Programming Guide by apple.

2.Understanding Key-Value Observing and Coding

Blocks in Objective-C — April 18, 2015

Blocks in Objective-C

Blocks in Objective-C allows you to store the chunks of code in variables. Blocks can be assigned to a variable , passed to functions, and generally treated like any other value. Also the blocks can be called as the function, and they capture the state of the things as they were when the block was created.

A simple block would look something like this :

int i = 5;
void (^someCode)() = ^{
NSLog(@"The value of i is %i", i);
};

We can invoke the above block like a function :

someCode();  //This prints  “The value of i is 5”

Here we see that the value of the variable ‘i‘ was captured during the creation of the block , hence it its value is 5 when used within the block. Thus when a variable outside a block is referenced within that block, the value of that variable at the moment of the block’s creation is captured and is available for the block’s code to use.

Blocks allow you to defer the execution of something until you need it to actually happen. This makes them very useful in the context of animations (“when the animation’s done, do this thing”), for networking (“when the download’s done, do something else”), or in general user interface manipulation (“when I return from this new screen, do some work”). They also allow you to keep related pieces of code close together. For eg:- using Blocks we can avoid writing a method to filter the array elements having prefix “Apple” as below.

// Filter an array of strings down to only strings that begin with the word
// "Apple"
NSPredicate* filterPredicate = [NSPredicate predicateWithBlock:^(id anObject) {
NSString* theString = anObject;
return [theString hasPrefix:@"Apple"];
}];
NSArray* filteredArray = [someArray filteredArrayWithPredicate:filterPredicate];

 Blocks Syntax

[Return Type] (^ [Variable Name]) ([Parameters]);

With reference to the above syntax we can define the block variable as shown:

  • A simple block which returns no value and takes no parameters will be defined in the following ways
void(^myBlockVariable)(void);      
void(^myBlockVariable)();    //Since the block takes no parameters
  •  A block block which takes input parameters will be defined by adding the parameters in the paranthesis at the end –
void(^myBlockVariable)(BOOL booleanParameter, NSString* objectParameter);

Once a block variable has been declared, it must have a block assigned to it before it can be called.

void(^myBlockVariable)(BOOL parameter);   //Declaration of the block variable
myBlockVariable = ^(BOOL parameter) {    // Assigning Block to the block variable   
// Code goes here.
};
                               
                                         ---OR---
void(^myBlockVariable)() = ^{ //Declaration and initialization of a block variable 
// Code goes here.                  //This block takes no parameters
};

Once we have defined the block it can be called as a we invoke the function like : myBlockVariable();

Using Blocks as parameter in Methods

Since the block in objective C is treated as any other value and assigned to a variable ,it can be passed as the parameter to a function. This is a key feature of the block ,since it allows the caller of the methods to provide the code at the moment they call the method.

The method accepting the block as a parameter can be declared as below:

- (void) someMethod:(void(^)(BOOL aParameter)) handler;

The implementation of this method would be:

- (void) someMethod:(void(^)(BOOL aParameter)) handler {
// Call the passed-in block:
handler(YES);
}                                        

We can call the above method like this

[anObject someMethod:^(BOOL aParameter) {
// The called method will call this method
}];

We can simplify the deceleration of the block variable by defining the block type , this reduces the amount of typing the code to declare a block variable and using it. Also it makes sure that all the block we use are of the same type.

// somewhere in your source code, outside of a function or method:
typedef void(^ABlockType)(BOOL aParameter);

// and later, in a function:
ABlockType myBlock = ^(BOOL aParameter) {
// do some work
};

We can use the above declared block as the method parameter as shown here:

- (void) someMethod:(ABlockType)handler; //This looks much tidier...!

Be Careful when using blocks

When a block is created, it is stored on the stack memory. So when we create a block, store it in a instance variable of the method , and then if we return from this method the block is removed from the memory but the instance variable still points to where it was. Thus on calling this block now would crash as the block no longer exists. This problem can be solved by copying the block to the heap , and making it to be in the memory as long as needed.

// myBlockProperty is a property of this class that can store the block.
void(^myBlockVariable)() = ^{
// code goes here
};
self.myBlockProperty = myBlockVariable; // INCORRECT! The block
// won't exist after this function returns, and calling it will crash.
self.myBlockProperty = [myBlockVariable copy]; // SAFE. The
// block will be copied and stored on the heap, and stick around.

Modifying the Local variables from within the block

Since the block captures the value of the variables that was during the creation of the block. In order to modify the value of this variable from within the block, we must declare the variable marked with the __block keyword.

__block int i = 0;                    //Declaring the variable with __block keyword
void(^myBlock)() = ^{                 // A simple block which modify the value of 'i'
i = 4;
};
myBlock();
NSLog(@"i is now %i", i);             // will print "i is now 4"
References:

Books: Learning Cocoa with Objective-C ,By -Jon Manning, Paris Buttfield-Addison, and Tim Nugent.

To know more:
Categories in Objective-C — April 4, 2015

Categories in Objective-C

Objective-C provides a feature for defining the new methods for an existing class even for the class whose source code is not available to you. One can make use of categories when their is a need to add new methods to the predefined classes such as COCOA classes-‘NSString etc.’ without sub-classing it .

A category is a group of methods for a class which are available to all through the class and can be used as the methods declared in the interface of the method. This helps to split up the class having numbers of methods in to several interface and implementation files, which helps in maintaining the large projects.The category name indicates that the methods are the additions for the class defined earlier and not a new class.

Consider a class ‘car’

// car.h

#import <Foundation/Foundation.h>

@interface Car : NSObject

-(void)startEngine;

-(void)applyBreak;

@end

Now consider the above ‘car’ class for which we want to add some new methods/capabilities (maintenance),we can do this by using categories as below.

// car+Maintenance.h

#import “car.h”

@interface Car (Maintenance)

-(void)maintainanceTyre;

-(void)maintainanceEngine;

@end

The implementation file for this category ‘maintenance’ would be as below:

// Car+Maintenance.m

#import Car+Maintenance.h

@implementation Car (Maintenance)

-(void)maintainanceTyre                                 //method 1 defination

{

}

-(void)maintainanceEngine                                 //method 2defination

{

}

@end

Now the methods ‘-(void)maintenanceTyre’  &  ‘-(void)maintenanceEngine’  will be available to all the objects of the ‘car‘ class.

#import <UIKit/UIKit.h>

#import Car.h

#import Car+Maintenance.h”                                      //category 

int main(int argc, char * argv[]){

@autoreleasepool {

Car *car1 = [[Car alloc] init];

//using methods from the class ‘car’

[car1 startEngine];

[car1 applyBreak];

//using additional methods from the category maintenance for the car1 object

[car1 maintenanceTyre];

[car1 maintenanceTyre];

}

}

Download : Sample XCode project on categories and extension Here!

Categories in Objective-C —

Categories in Objective-C

Objective-C provides a feature for defining the new methods for an existing class even for the class whose source code is not available to you. One can make use of categories when their is a need to add new methods to the predefined classes such as COCOA classes-‘NSString etc.’ without sub-classing it .

A category is a group of methods for a class which are available to all through the class and can be used as the methods declared in the interface of the method. This helps to split up the class having numbers of methods in to several interface and implementation files, which helps in maintaining the large projects.The category name indicates that the methods are the additions for the class defined earlier and not a new class.

Consider a class ‘car’

// car.h

#import <Foundation/Foundation.h>

@interface Car : NSObject

-(void)startEngine;

-(void)applyBreak;

@end

Now consider the above ‘car’ class for which we want to add some new methods/capabilities (maintenance),we can do this by using categories as below.

// car+Maintenance.h

#import “car.h”

@interface Car (Maintenance)

-(void)maintainanceTyre;

-(void)maintainanceEngine;

@end

The implementation file for this category ‘maintenance’ would be as below:

// Car+Maintenance.m

#import Car+Maintenance.h

@implementation Car (Maintenance)

-(void)maintainanceTyre                                 //method 1 defination

{

}

-(void)maintainanceEngine                                 //method 2defination

{

}

@end

Now the methods ‘-(void)maintenanceTyre’  &  ‘-(void)maintenanceEngine’  will be available to all the objects of the ‘car‘ class.

#import <UIKit/UIKit.h>

#import Car.h

#import Car+Maintenance.h”                                      //category 

int main(int argc, char * argv[]){

@autoreleasepool {

Car *car1 = [[Car alloc] init];

//using methods from the class ‘car’

[car1 startEngine];

[car1 applyBreak];

//using additional methods from the category maintenance for the car1 object

[car1 maintenanceTyre];

[car1 maintenanceTyre];

}

}

Download : Sample XCode project on categories and extension Here!