
What is an object within Objective-C?
How do things work inside Objective-C? NSObject
is the root class of most Objective-C class hierarchies, through it an object inherits basic methods and behaves like an Objective-C object.
This object is an instance of a class and can also be a member of a class or one of its derivatives. So, let's take a deeper look at NSObject
. In the early stage, Objective-C had a class called Object
. This had a method called +new
, which wrapped malloc()
, and a method called -free
. Since Objective-C objects were generally aliased and managing object life cycles became quite complex, this was troublesome.
NSObject is used by NeXT—Steve Job's second company, founded after he was fired from Apple in 1985—in order to provide reference counting, thus, dividing Object pointers in two categories: pointers that own references and pointers that do not own references. Those pointers that contribute towards the object's reference count are owning reference pointers. If there is a certainty that a reference is going to be held somewhere else for the duration of a variable's lifetime, a non-owning reference pointer can be used avoiding the additional overhead of reference count manipulation since a non-owning reference pointer does not have the added cost of keeping track of object ownership.
Non-owning reference pointers are often used for autoreleased values. Autorelease pools make it possible for a temporary object to receive a non-owning reference pointer in return. An object, by receiving an -autorelease
message is added to a list that will be deallocated afterwards, with the destruction of the current autorelease pool. You can call autorelease using the autorelease method as shown here:
[myObject autorelease];
The following table shows some description on the roles of autorelease and release:

Any object that receives the autorelease message will be released when the autorelease pool is drained. Using autorelease instead of the normal release method will extend the lifetime of an object until the pool is drained at the end of the run loop.
At Worldwide Developers Conference (WWDC) 2011, Apple introduced ARC, the acronym of Automatic Reference Counting. It forces the compiler to handle the memory management calls at compile time instead of the conventional garbage collection functionality, which occurs during runtime. ARC also adds some things to the language model in general. It has been supported since iOS5, OS X 10.7, and by GNUstep.
First, what we will find out is that there are two NSObjects in Cocoa, a class and a protocol. Why is this so and what is the purpose of this? Let's look into classes and protocols.
In Objective-C, protocols define a set of behaviors that an object is expected to conform to in certain situations at runtime. For example, a table view object is expected to be able to communicate with a certain data source so that the table view will know what data and information to display. Protocols and classes do not share the same namespaces (a set of identifiers containing names, the names of classes and protocols, thus the same name can exist in different namespaces). It's possible to have both, which are unrelated at the language level, but have the same name. This is the case with NSObject.
If you look at the language, there are no places where you can use either a protocol or a class name. Using class names as the target of message sends, as type names, and in @interface
declarations is allowed. Likewise, it's possible to use protocols names in a few identical places; however, not in the same way. Having a protocol with the same name as a class won't result any issue.
It is impossible for root class to have a superclass as they are at the top of the hierarchy, so there is no superclass above a root class and NSObject class is one of them. And I give emphasis on saying one of them because in comparison to other programming languages in Objective-C, it's perfectly possible to have the existence of multiple root classes.
Java's single root class is named java.lang.Object
, which is the parent ultimate class of any other. For this reason, any piece of code in Java, which comes from any object, has the basic methods added by java.lang.Object
.
Cocoa can have multiple root classes. Besides NSObject
, there is NSProxy
and a few others root classes; and such root classes are, in part, the reason for the existence of the NSObject
protocol. The NSObject
protocol determines a specific set of basic methods, expecting their implementation by the others root classes, consequently, making those methods available whenever and wherever they are needed.
The NSObject
class is in accordance to the NSObject
protocol, which results in the implementation of this basic method:
//for NSObject class @interface NSObject <NSObject>
Implementing the same method works for NSProxy
, which is also in accordance to the NSObject
protocol:
// for NSProxy class @interface NSProxy <NSObject>
Methods such as hash, description, isEqual
, isKindOfClass
, isProxy
, and others are found in the NSObject
protocol. NSProxy
to NSObject
protocol denotes that, implementing the basic NSObject
methods, it's still possible to count on NSProxy
instances.
Subclassing NSObject
would pull in a lot of baggage that may cause a problem. NSProxy
assists in order to prevent this by giving you a simpler superclass that doesn't have so much extra stuff in it.
The fact that the NSObject
protocol is useful for root classes isn't all that interesting for most Objective-C programming, for the simple fact that we don't make use of other root classes frequently. However, it will be very convenient when you need to make your own protocols.
Let's say, you have the following protocol:
@protocol MyOwnProtocol - (void)myFunction; @end
And there is a pointer to a simple object, myOwnObject
, that accords to it:
id<MyProtocol> myOwnObject;
You can tell this object to perform myFunction
:
[myOwnObject myFunction];
However, you cannot ask the object for its description:
[myOwnObject description]; // no such method in the protocol
And you can't check it for equality:
[myOwnObject isEqual: anotherObject]; // no such method in the protocol
In general, you can't ask it to do any of the stuff that a normal object can do. There are times when this doesn't have any importance, but in some circumstances, you will wish to be able to perform this task.
As mentioned earlier, NSObject
, the root class of most Objective-C class hierarchies and through NSObjects
, your Objective-C classes can inherit an interface to the system and also gain the ability to behave as Objective-C objects. So, NSObject
is important if you want your objects to gain access to methods such as isEqual
, so on, and so forth. This is where the NSObject
protocol comes into the picture. Protocols can inherit from other protocols, which means that MyProtocol
can inherit from the NSObject
protocol:
@protocol MyOwnProtocol <NSObject> - (void)myFunction; @end
This says that not only do objects that conform to MyOwnProtocol
respond to myFunction
, but they also respond to all those common messages in the NSObject
protocol. Knowing that any object in your application directly or indirectly inherits from the NSObject
class, that it's in accordance to the NSObject
protocol, there is no imposition to any additional requirements on people implementing MyOwnProtocol
, while giving you the permission to use these basic methods on instances.
Note
The fact that there are two different NSObjects is abnormal for the frameworks; however, it starts to make sense when you go deeper into it. The NSObject
protocol grants the permission to all root classes that have the same basic methods, making, also, a very easy way to declare a protocol that also includes basic functionality expected from any object. The NSObject
class introduces it all together, since it's in accordance to the NSObject
protocol. One thing to note here is that a custom class that's created and does not inherit NSObject
can be considered as a root class, but once you make your custom class inherit from NSObject
, then the root class won't be your custom class anymore, and the root class will be NSObject
. However, generally, most of your custom classes should inherit from NSObjects; it will implement NSObject's functionality such as alloc
, init
, release
, and so on and without inheriting from NSObject, these functionalities need to be written and implemented by you.