The "C" language
As the name refers, "Objective-C", is just a superset of "C-Language". Superset?
It actually means, anything that is true in the C-Language, can be applied to Objective-C.
But to write code for iOS, everything has to be written in accordance with the iOS API(Application Programming Interface). So, before writing anything in Objective-C, a basic knowledge in "C" is required. There are a lot of sources to learn "C" from online.
It's important to learn "C " first, since C function calls and C data structures is needed while writing in Objective-C.
For instance, the data structure CGPoint represents a point in a two dimensional co-ordinate system. So, to create a
point that takes two numbers as arguments, the C- function CGPointmake has to be called. The iOS API doumentation contains some C functions like this and the basic knowledge of C language is expected.
DATA TYPES
In "C" there are built in data types like int(takes 4 bytes of memory), char(takes 1 byte of memory), float(takes 4 bytes with different Range) and then there are Long, Unsigned int etc.
Similarly, in Objective-C, NSInteger is same as "int" and CGFloat is same as float.
It actually means, anything that is true in the C-Language, can be applied to Objective-C.
But to write code for iOS, everything has to be written in accordance with the iOS API(Application Programming Interface). So, before writing anything in Objective-C, a basic knowledge in "C" is required. There are a lot of sources to learn "C" from online.
It's important to learn "C " first, since C function calls and C data structures is needed while writing in Objective-C.
For instance, the data structure CGPoint represents a point in a two dimensional co-ordinate system. So, to create a
point that takes two numbers as arguments, the C- function CGPointmake has to be called. The iOS API doumentation contains some C functions like this and the basic knowledge of C language is expected.
DATA TYPES
In "C" there are built in data types like int(takes 4 bytes of memory), char(takes 1 byte of memory), float(takes 4 bytes with different Range) and then there are Long, Unsigned int etc.
Similarly, in Objective-C, NSInteger is same as "int" and CGFloat is same as float.
Encapsulation
Encapsulation, is a Object-Oriented terminology, that defines a mechanism of the language where the data is bundled with the functions or methods that operates on those data members. It is also sometimes refers to the access to some of the components of the Objects too.
In C Language, to represent complex data types, the three ways are, ARRAYS, POINTERS and STRUCTURES. From these, most important parts are the notion of pointers and structures , since Objective-C it has it's own object type called, NSArray.
In "C", struct is the short form of structures. CGPoint is a perfect example for C structure.
STRUCT/CLASS
In iOS documentation, a struct CGPoint is defined like this-
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
Now, class is only needed when we have an invariant i.e if we need to hide some data that needs to be protected from changing by anyone, then, we write class instead of struct.
Here, CGPoint has two data members where, x and y is CGFloat which is actually same as float in "C". How can we assign values to those memebers? Well, one of the ways follows this rule-
name of the struct . name of the data member = value; //assigning value to data members
Here, name of the struct is CGPoint. The last line used a keyword called "typedef" which is making things easier to write, so that we don't have to write "struct CGPoint" everytime ; instead we write just "CGPoint".
So, following the rule above, to access the data members, we write,
CGPoint point; //creating an object from CGPoint
point.x = 100; /* accesing the data members
point.y = 200; of CGpoint */
struct/Object/Instance:
In the lines above, point can be called object of CGPoint or instance of CGPoint.
A struct is a blueprint of the object which does not take any memory, it is just a description of the object to be created.
An object is just a memory space that carries all the properties and attributes described inside the struct.
Now, the synonym of the word instance is example or single occurrence of something. So, we can say, an object can be an instance of a struct or class.
The memebers of a struct can be another struct. For instance,
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGPoint CGpoint;
Now, we have two structs, "CGPoint" and "CGSize", now another struct "CGRect" can be made out of these two structs!
struct CGRect {
CGPoint vertex; //vertex is an instance of CGPoint
CGSize dimension; //dimension is an instance of CGSize
};
typedef struct CGRect CGRect;
If we create an object using the CGRect struct called "rectangle" then to change the height of CGRect by writing this code,
rectangle.dimension.height = 10.8;
The codes written above are not the only techniques to initialize the variables. For example,
instead of writing
CGPoint point;
point.x = 100;
point.y = 200;
we can write
CGPoint point = {100 , 200};
and to change the properties of rectangle we can also write,
CGRect rectangle = { point , { 5 ,10.8 } }; // width is 5 and height is 10.8
In C Language, to represent complex data types, the three ways are, ARRAYS, POINTERS and STRUCTURES. From these, most important parts are the notion of pointers and structures , since Objective-C it has it's own object type called, NSArray.
In "C", struct is the short form of structures. CGPoint is a perfect example for C structure.
STRUCT/CLASS
In iOS documentation, a struct CGPoint is defined like this-
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
Now, class is only needed when we have an invariant i.e if we need to hide some data that needs to be protected from changing by anyone, then, we write class instead of struct.
Here, CGPoint has two data members where, x and y is CGFloat which is actually same as float in "C". How can we assign values to those memebers? Well, one of the ways follows this rule-
name of the struct . name of the data member = value; //assigning value to data members
Here, name of the struct is CGPoint. The last line used a keyword called "typedef" which is making things easier to write, so that we don't have to write "struct CGPoint" everytime ; instead we write just "CGPoint".
So, following the rule above, to access the data members, we write,
CGPoint point; //creating an object from CGPoint
point.x = 100; /* accesing the data members
point.y = 200; of CGpoint */
struct/Object/Instance:
In the lines above, point can be called object of CGPoint or instance of CGPoint.
A struct is a blueprint of the object which does not take any memory, it is just a description of the object to be created.
An object is just a memory space that carries all the properties and attributes described inside the struct.
Now, the synonym of the word instance is example or single occurrence of something. So, we can say, an object can be an instance of a struct or class.
The memebers of a struct can be another struct. For instance,
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGPoint CGpoint;
Now, we have two structs, "CGPoint" and "CGSize", now another struct "CGRect" can be made out of these two structs!
struct CGRect {
CGPoint vertex; //vertex is an instance of CGPoint
CGSize dimension; //dimension is an instance of CGSize
};
typedef struct CGRect CGRect;
If we create an object using the CGRect struct called "rectangle" then to change the height of CGRect by writing this code,
rectangle.dimension.height = 10.8;
The codes written above are not the only techniques to initialize the variables. For example,
instead of writing
CGPoint point;
point.x = 100;
point.y = 200;
we can write
CGPoint point = {100 , 200};
and to change the properties of rectangle we can also write,
CGRect rectangle = { point , { 5 ,10.8 } }; // width is 5 and height is 10.8
Array
In "C" Language, an array is a container, that contains different elements of same data type. An array declaration goes like this,
float elements [5]; // elements can carry five elements of float data types.
and this is how we initialize elements of an array.
float elements [0] = 15.4 ;
float elements [1] = 7.9 ;
float elements [2] = 13.4 ;
In "C", the index of the array starts from "0", i.e the "0" represents the first element of the array. Most of the languages follow the same convention. It is interesting that some language allows you to start array index from whatever number you want.
Such as arrays in LUA which a famous among the game programmers now-a-days.
C array's are sometimes useful while programming in Objective-C. Taking the following function for example,
void CGContextStrokeLineSegments (
CGContextRef c,
const CGPoint points[],
size_t count
);
Here, the second parameter is an array of CGPoints. If we initialize an array of points like this,
CGPoint points [ ] = { { 5 , 4 }, {6 , 7 }, {4 , 8 } };
and this can be passed as a second argument when calling the "CGContextStrokeLineSegments" function.
In Obejctive-C, we work with arrays using the foundation framework NSArray class and unlike "C" the objects inside the array does not have to be of same data type. Sounds pretty convenient to me.
In Objective-C the class NSArray contains a method called arrayWithObjects. By calling this method, we can create an array
that can hold elements. For example,
NSArray *mybag;
myBag = [ NSArray arrayWithObjects : @"pencil", @"eraser", @ " calculator ", nil ];
In the code above, an array object called "myBag" is created that contains strings, pencil,eraser and calculator. Here, a nil entry is required, so that any other method that will work on this array can find the end of this array.
float elements [5]; // elements can carry five elements of float data types.
and this is how we initialize elements of an array.
float elements [0] = 15.4 ;
float elements [1] = 7.9 ;
float elements [2] = 13.4 ;
In "C", the index of the array starts from "0", i.e the "0" represents the first element of the array. Most of the languages follow the same convention. It is interesting that some language allows you to start array index from whatever number you want.
Such as arrays in LUA which a famous among the game programmers now-a-days.
C array's are sometimes useful while programming in Objective-C. Taking the following function for example,
void CGContextStrokeLineSegments (
CGContextRef c,
const CGPoint points[],
size_t count
);
Here, the second parameter is an array of CGPoints. If we initialize an array of points like this,
CGPoint points [ ] = { { 5 , 4 }, {6 , 7 }, {4 , 8 } };
and this can be passed as a second argument when calling the "CGContextStrokeLineSegments" function.
In Obejctive-C, we work with arrays using the foundation framework NSArray class and unlike "C" the objects inside the array does not have to be of same data type. Sounds pretty convenient to me.
In Objective-C the class NSArray contains a method called arrayWithObjects. By calling this method, we can create an array
that can hold elements. For example,
NSArray *mybag;
myBag = [ NSArray arrayWithObjects : @"pencil", @"eraser", @ " calculator ", nil ];
In the code above, an array object called "myBag" is created that contains strings, pencil,eraser and calculator. Here, a nil entry is required, so that any other method that will work on this array can find the end of this array.
POINters
The name tells us that it's job is to point to something. Here, by pointing it means, holding the address of the memory location to where it is pointing to. It is said that a picture worth thousand words. So, here is a reference from wikipedia that shows a pointer variable that is holding a specific memory address, i.e pointing to it.
Link : Pointer (Wikipedia)
In C , if we have to declare a pointer variable that can point to any integer type data we write it like this,
int* ptr ; // ptr is a pointer to integer
It is permitted to put the asterisk symbol before the variable name rather than the type. So, this is also a valid line to write,
int *ptr ;
even this will be also valid,
int * ptr ;
But usually most programmers prefer the first way. Other than the declaration, if we write, just *ptr, it means " the thing ptr is pointing to". This is called differencing the pointer.
A pointer that points to nothing is called a void pointer. We just write,
void* ptr ; // ptr is point to nothing.
An interesting fact is, if we write two pointers and assign one pointer to another, both of them will be pointing to the same object.
For example,
int* a = 1;
int* b = 2;
Now if we write,
a = b ;
This actually means , whatever a is pointing to , b is pointing to the same thing.
Link : Pointer (Wikipedia)
In C , if we have to declare a pointer variable that can point to any integer type data we write it like this,
int* ptr ; // ptr is a pointer to integer
It is permitted to put the asterisk symbol before the variable name rather than the type. So, this is also a valid line to write,
int *ptr ;
even this will be also valid,
int * ptr ;
But usually most programmers prefer the first way. Other than the declaration, if we write, just *ptr, it means " the thing ptr is pointing to". This is called differencing the pointer.
A pointer that points to nothing is called a void pointer. We just write,
void* ptr ; // ptr is point to nothing.
An interesting fact is, if we write two pointers and assign one pointer to another, both of them will be pointing to the same object.
For example,
int* a = 1;
int* b = 2;
Now if we write,
a = b ;
This actually means , whatever a is pointing to , b is pointing to the same thing.
The notion of pointer must be clear before coding in Objective-C, since every variable that is referring to an object is a pointer !
The Objecttive-C string type is called NSString. If we declare a pointer ptr that points an NSString type is written as ,
NSString* ptr ;
and we can assign a value to this pointer variable like this,
NSString* ptr = @"Write code";
The "@" sign is actually a directive to the objective-C compiler to form an NSString Object. The pointer *ptr is pointing to the NSString literal "Write code".
Now the line, NSString* ptr ; if used without ARC then it will create a dangerous situation.
It looks like ptr is pointing to NSString type but there is no value assigned to it. Here, ptr can point to anything which is usually called a garbage value.
Now, under ARC, it is automatically set to nil as soon as someone declares a pointer without initializing it that was a real headache for the ios developers before ARC arrived. But now uneder ARC, this line,
NSString* ptr ;
is actually means this,
NSString* ptr = nil ; // ARC invisibly set the pointer to zero for the developer.
The Objecttive-C string type is called NSString. If we declare a pointer ptr that points an NSString type is written as ,
NSString* ptr ;
and we can assign a value to this pointer variable like this,
NSString* ptr = @"Write code";
The "@" sign is actually a directive to the objective-C compiler to form an NSString Object. The pointer *ptr is pointing to the NSString literal "Write code".
Now the line, NSString* ptr ; if used without ARC then it will create a dangerous situation.
It looks like ptr is pointing to NSString type but there is no value assigned to it. Here, ptr can point to anything which is usually called a garbage value.
Now, under ARC, it is automatically set to nil as soon as someone declares a pointer without initializing it that was a real headache for the ios developers before ARC arrived. But now uneder ARC, this line,
NSString* ptr ;
is actually means this,
NSString* ptr = nil ; // ARC invisibly set the pointer to zero for the developer.
C -functions
In "C" a function is a block of code, that defines what should happen when we call it, or invoke it. Sometimes, it returns a value, sometimes it not.The function that doesn't return a value is called a void function. It calculates something for us but doesn't return anything.
A sample C function will be,
int cube (int a) {
return a * a * a ;
}
If we call this function, it will be like this,
int a = cube (2) ; // the cube function calculates the value of 2^3 and store it in a
or
int a = 8 ;
So, the above function returns a int type value, takes one int type arguments as it's parameter which is "a", and finnaly it calculates the cube of that number by multiplying the same number three times and returns the final value that can be stored in any variable of type int or double.
Difference between Objective-C and C-Function:
Now the main difference between Objective-C and C function is to call an Objective-C method, we send message to an object which will be inside a square brackets but to call a C-Function we use the functions name followed by the parentheses containing the arguments.
Objective-C class Implementation:
In any language, when we write a class, it has two parts as class interface and class implementation. Here's an example of an objective-C class definition without any methods and let's name it Bird"
@interface Bird
@end
@implementation Bird
@end
_When we are defining class, it is the implementation section where the methods for this class goes.
For example, the "Bird" class can have a method like this:
@implementation Bird
-(NSString*) itsEveningNow {
return @"time to return to the nest!";
}
@end
Before we discuss about the message and methods of Objective-C, we should know a couple of other important things.You would be surprised to know that the class we defined above cannot be instantiated. There are two reasons, one is we didn't declare the method name in the interface section and this class is of no good if we do not make it inherit from the Cocoa base Class called NSObject.
So, following the ususal convention
MESSAGE & METHOD
In Object-Oriented language a command to the object is called a message. We send a message to an object and expect it to do something and this whole process is called calling a method. In Object-based language, we say method instead of function, i.e it is the same thing. When we send a message to an object it responds by calling the specific method that will set it's behavior that we are expecting from it.
We talked about classes and instances earlier, class and struct is almost the same , but class carries some restricted information on the other hand struct is free to public.
Now,method are of two types in Objecttive-C.
1. Class Method
2. Instance Method
If mehtod is a class method , we can send the messege to the class. In Apple's API, we can tell the difference between class method and instance method by looking at the "+" sign and "-" sign. For example,
+ string
- init
Here, string is a class method and init is a instance method of the class.
We should keep in mind three things while working with messages and methods.
1. If it is a class method, we call it by sending a message to the class. If it is a instance method, we call it by sending a message to an instance of the class.
2. It's parameter's and return value. In Objective-C , methods takes some parameters of specific type like C functions and returns a value which is also a specific type. If the method returns nothing, it will be a void method.
3. In an objective-C method, the number of colons is equal to the number of parameters. If the method takes any parameters, the method name should end with a colon.
Examples:
The syntax to send the message to an object requires square brackets.
NSString* a = [b lowercaseString];
Here, b is the object that is receiving the message which is lowercaseString. Now if, we click on the apple's documentation
for the method "lowercaseString" we can see that it is an instance method. If b contains something with the upper case letter like this, "HELLO", then after calling this method, variable "a" stores the string value "hello".
To call a class method, we just simply send the message directly to the class, like this,
NSString* a = [NSString string];
The code above is not a Objective -C code, it is just a way of saying that the class NSString is receiving a message "string".
Declaring a Method:
We should remember three things when declaring a method.
1. "+" means sign means that it is a class method or "-" sign means it is a instance mehtod.
2. The data type of the value that will be returned by the method is in parentheses like this +(NSArray *).
3. The name of the method ends with a colon and following each colon is the corresponding parameter with their data type inside the parentheses followed by a placeholder name for that parameter.
In the UIColor class Reference in Apple's API, in the long list of methods, if we see this method,
+ (UIColor*)colorWithWhite:(CGFloat)white alpha:(CGFloat) alpha
The above method is a class method that returns a UIColor, takes two parameters since there are two colons, and their type is a "CGFloat" and the first one represent a white color and second one represents the visibility i.e alpha.
Therefore, this method takes two arguments of type "CGFloat" and returns "UIColor".
To declare a method in Objective-C, follow the following format:
-(type I return)nameOfMethod: (type of first parameter) firstParameter continuationOfMethodName: (type of second parameter) secondParameter
A sample C function will be,
int cube (int a) {
return a * a * a ;
}
If we call this function, it will be like this,
int a = cube (2) ; // the cube function calculates the value of 2^3 and store it in a
or
int a = 8 ;
So, the above function returns a int type value, takes one int type arguments as it's parameter which is "a", and finnaly it calculates the cube of that number by multiplying the same number three times and returns the final value that can be stored in any variable of type int or double.
Difference between Objective-C and C-Function:
Now the main difference between Objective-C and C function is to call an Objective-C method, we send message to an object which will be inside a square brackets but to call a C-Function we use the functions name followed by the parentheses containing the arguments.
Objective-C class Implementation:
In any language, when we write a class, it has two parts as class interface and class implementation. Here's an example of an objective-C class definition without any methods and let's name it Bird"
@interface Bird
@end
@implementation Bird
@end
_When we are defining class, it is the implementation section where the methods for this class goes.
For example, the "Bird" class can have a method like this:
@implementation Bird
-(NSString*) itsEveningNow {
return @"time to return to the nest!";
}
@end
Before we discuss about the message and methods of Objective-C, we should know a couple of other important things.You would be surprised to know that the class we defined above cannot be instantiated. There are two reasons, one is we didn't declare the method name in the interface section and this class is of no good if we do not make it inherit from the Cocoa base Class called NSObject.
So, following the ususal convention
MESSAGE & METHOD
In Object-Oriented language a command to the object is called a message. We send a message to an object and expect it to do something and this whole process is called calling a method. In Object-based language, we say method instead of function, i.e it is the same thing. When we send a message to an object it responds by calling the specific method that will set it's behavior that we are expecting from it.
We talked about classes and instances earlier, class and struct is almost the same , but class carries some restricted information on the other hand struct is free to public.
Now,method are of two types in Objecttive-C.
1. Class Method
2. Instance Method
If mehtod is a class method , we can send the messege to the class. In Apple's API, we can tell the difference between class method and instance method by looking at the "+" sign and "-" sign. For example,
+ string
- init
Here, string is a class method and init is a instance method of the class.
We should keep in mind three things while working with messages and methods.
1. If it is a class method, we call it by sending a message to the class. If it is a instance method, we call it by sending a message to an instance of the class.
2. It's parameter's and return value. In Objective-C , methods takes some parameters of specific type like C functions and returns a value which is also a specific type. If the method returns nothing, it will be a void method.
3. In an objective-C method, the number of colons is equal to the number of parameters. If the method takes any parameters, the method name should end with a colon.
Examples:
The syntax to send the message to an object requires square brackets.
NSString* a = [b lowercaseString];
Here, b is the object that is receiving the message which is lowercaseString. Now if, we click on the apple's documentation
for the method "lowercaseString" we can see that it is an instance method. If b contains something with the upper case letter like this, "HELLO", then after calling this method, variable "a" stores the string value "hello".
To call a class method, we just simply send the message directly to the class, like this,
NSString* a = [NSString string];
The code above is not a Objective -C code, it is just a way of saying that the class NSString is receiving a message "string".
Declaring a Method:
We should remember three things when declaring a method.
1. "+" means sign means that it is a class method or "-" sign means it is a instance mehtod.
2. The data type of the value that will be returned by the method is in parentheses like this +(NSArray *).
3. The name of the method ends with a colon and following each colon is the corresponding parameter with their data type inside the parentheses followed by a placeholder name for that parameter.
In the UIColor class Reference in Apple's API, in the long list of methods, if we see this method,
+ (UIColor*)colorWithWhite:(CGFloat)white alpha:(CGFloat) alpha
The above method is a class method that returns a UIColor, takes two parameters since there are two colons, and their type is a "CGFloat" and the first one represent a white color and second one represents the visibility i.e alpha.
Therefore, this method takes two arguments of type "CGFloat" and returns "UIColor".
To declare a method in Objective-C, follow the following format:
-(type I return)nameOfMethod: (type of first parameter) firstParameter continuationOfMethodName: (type of second parameter) secondParameter