Objective-C Programming/concepts
Please correct the title of this work to conform with Wikibooks' naming policy. You can help by renaming all affected pages and links, including this page. You can also share your thoughts, or ask for assistance in the project room. |
There are a number of key Objective-C concepts that have close relations to the practice of object-oriented programming in general. For the moment, we won't look at exact syntax until later.
- If you have previous experience in object-oriented programming, you may wish to skip these sections and examine the Summary section
Objective-C is just C (a superset of C) , with Lisp like object-oriented syntax
[edit | edit source]Object-orientation in objective-C has some similarities with C++ , and is a way of organising memory like c-style structs, except that it is expected that the structures have pointers to functions that can reference any offset defined as an instance variable or function pointer , so the object is a memory location from which the offsets to instance variables can be found , and where there is a pointer back to the class definition that gives the addresses of functions of the class.
In C++, to call a member function from a member function of a class, the syntax is
this -> func ( a, b );
or
(*this).func (a, b);
this represents a pointer to "this" object , the instance of a class which defined the function where "this" is being used .
In objective-C , 'self' is the keyword to replace 'this', and the invocation would be
[self func: a, b ]
So here, the parameters to the function are not enclosed in parentheses like most other c based languages, but
Constructors in java are called like this in a constructor of a child class, when the parent class's constructor needs to be invoked .
Child( a, b, c ) { super(a); this.b = b; this.c = c; }
Similarly, in objective-C , for a class interface
@interface MyClass : MyParentClass { MyClassB * b; int c; } @property (copy, nonatomic) NSInteger d;
-(void) func1; -(void) func2: (int)param1, (id) param2; @end
there is an elided init constructor function, and
the constructor might be
- (id) init: (id)a, (id) b, (int) c , (NSInteger) d { self = [super init:a ]; // -(2) if (self) { _b = [[B alloc] initByCopy:b] ; _c = c; self.d = d; } return self; }
and there exists a constructor for MyParentClass , which is
- (id) init: (id) a // - (2a) { .. }
The above example shows:
- id is a placeholder for a class type.
- In a function declaration or definition, parentheses are conventionally put around the return type, and before each parameter to give their types.
- self is a supplied instance variable that references an object of the class, but can be initially an object of the supertype , as in (2) and (2a).
- the convention is to call alloc which is a class function for a class to obtain an object, and then to initialize the object by calling an object function with a function conventionally being 'init' or beginning with 'init..' , so the pattern is my_object = [[A_Class alloc] init:a_param1, a_param2], which means "allocate the memory for an object templated by A_Class, and then call init on the object with a_param1 and a_param2".
- some simple C language types such as int, double, char* , can be represented by more complex classes beginning with NS.
- In the above example, _b and _c don't have self preceding it , but d does. d is defined as a property in the interface declaration part of the class. A property has elided set/get functions for the instance variable, and can have property attributes like ( copy, nonatomic ) - copy means "self.d = d" is short for "self.d = [ [NSInteger alloc] initByCopy:d ] , where NSInteger is the class for d.
- it's helpful to remember that objective-C is an extension of c, and variable names usually refer to a short sequence of 4, 8 or 16 bytes , which either represent numbers (int, long, float, double, char) or addresses ( char* , class instance pointers ). This is a bit unlike java, where variables are references to objects, and it is elided or hidden how the objects are referenced, and how their memory is managed. Objective-c frameworks added in reference-counting automatic deallocating memory management later to the NS.. classes family.
C and Standard Unix system interface underlie Objective C
[edit | edit source]Any of the standard Unix libraries which are available in C are available in Objective C , so this includes standard system interfaces to services such as file input/output, dynamic ( malloc/free ) allocation, string functions, maths functions, process creation, synchronization, and interprocess communication via file locks, thread locks, thread condition variables, semaphores, pipes, sockets, shared memory management, signals. However, objective C allows grouping of data structures with methods, and gives rise to shortcut organizing structured programming for domains such as GUI construction, using object-oriented patterns such as polymorphism and delegation ( via objective-c "protocol" feature ). Additional features also include automated references counting so that dynamic allocated objects are automatically deallocated without garbage collection. This gives rise to replacement of standard operating system interface functions (malloc/free) , with standard objective c. object oriented idioms from NSObject e.g.
NS<some class>* p = [[NS<some class> alloc] init] ;
for those familiar to dot only syntax eg java , means same as
MYClass p = (MyClass.alloc()).init();
"Call static factory class method alloc(), and invoke init() on object."
In c, there is only
MyStruct * p = malloc ( size of(MyStruct));
later on, the pointer p may share the memory address with another pointer, say q, and there would be 2 references, then if later, q = z, and even later p= z, but wait, there is a memory leak, so free() must be called on p because it is the last reference to the memory allocation produced by the call to malloc above.
free(p);
In older objective c frameworks,
[p dealloc];
However, automatic reference counting or ARC, means that when p = z, in the example above, the reference count for the NS object pointed to by p falls to zero, and free() is called on the hidden pointer held by the ARC support framework.
Example 2, instead of
char * charbuf[maxlength]; snprintf ( charbuf, maxlength-1, "hello %s , %d times!", "world", 2);
there is
NSString* mystrbuf = [[NSString alloc] initWithFormat: "hello %s , %d times!", "world", 2];
What is object-oriented programming?
[edit | edit source]Object-oriented programming (often just shortened to OO or OOP), is a programming paradigm where code is written in units called classes, where functions associated with data structures are declared and defined together. For example, ANSI C has data in structs, and similarly, an OO language stores data in classes or objects, but also declares the functions that operate on instances of structured data (objects). A class itself can be an object, with associated data and class functions, but there is only one instance per process space. (in general, operating systems have one process per running program, but allow multiprocess programs which are programs that start off other programs ).
For example, if you are creating a word processor, you might represent the document by an object that has text as its data, and associate with it different tasks to perform upon the document's data, such as "spell check".
The word processor then would be a small program that might draw the window and show the document's text. A spell check button would perform the "spell check" task upon that document's object.
However, if we were editing two documents at once, they would differ probably in the contents of the documents- the data. But all the documents would be more or less the same: Each document contains a space for its text, and has a couple of defined tasks that operate on the text. Each document object has essentially the same form. We call this form the class of the object, and we often give it a name. Let's call the document class Document (Style note: we often capitalize names of classes).
Now, each document object has the form of the Document. We say that each document object is an instance of Document. So, for example, our word processor operates on instances of the Document class. Sometimes we may call an instance of the Document class just "a Document".
Remember that each object has some data. For example, with the Document class, each Document has data to hold the text of the document. We call the data that each object holds instance variables. So, a Document may specify an instance variable to hold the text, or an instance variable to hold the word count, or the author, or any other data we may want to specify. Each Document has instance variables that are separate from the instance variables of any other Document that may exist.
Each object also has a number of tasks that it can perform on its instance variables. In Objective-C, we call these tasks methods. The object's methods operate on the object's instance variables.
However, there's more to objects than just this. With Objective-C, we can do a lot of interesting things with objects.
Working with objects
[edit | edit source]Let's stick with the example of our word processor. Say we want to create a new instance of Document so we can work with it. This process is called instantiation.
Now that we have an active instance of an object, we can work with it, by using the object's methods. We'll look at defining and working with methods later. Each method merely acts like a function in C, and in Objective-C, there is only a minor syntax change.
When we're completely done with the object and want to get rid of it (so it stops taking up memory), we do what is known as destruction or deallocation of the object. This is like free'ing a malloc'd array, for example, in C. However, if, in the process of using the object's methods, we allocate some extra memory for its instance variables, we must free that memory too.
Object techniques
[edit | edit source]When we're creating new classes, we may want to base the new object's behaviour on a class, which we have previously created. For example, if we want to create a document class that has details of style information, we may wish to base that class on the `Document` class, which we have previously created.
This is a common enough feature that it is included in object-oriented systems, and it is given the name of inheritance. When a class inherits from another, the new class takes on the form of the old class and can add extra instance variables and methods.
So, if we wanted to create a `StyledDocument` class, we would inherit from the `Document` class. In Objective-C, a class only inherits from one other class. This is known as single inheritance.
Interfaces and implementation
[edit | edit source]As in the real world, there is a separation between how objects are used, and how objects work. For example, with our word processor, there is a consistent interface to the spellchecker (how it is used), such as buttons to jump to the next misspelt word, to go back, and to correct. But, behind the scenes, the way the spellchecker works (the implementation) can be done in many different ways.
In Objective-C, the interface and implementation are kept separate. This allows different objects to work and link together in a well-defined manner. To change channels on your television, for example, you use the interface of the buttons on the television set instead of opening it and fiddling around with the electronics.
Keeping the implementation separate from the interface means that we can change anything in the implementation (even substituting it with another implementation) and everything should still work, because objects (buttons etc) interact with each other only through their interfaces.
Summary
[edit | edit source]So, before we get to learning Objective-C syntax, let's recap:
- An object is an instance of a class
- which has defined upon it tasks known as methods
- and data known as instance variables
- which has defined upon it tasks known as methods
- A class can inherit from one (and only one) other class (single inheritance)