开发者

Class Objects and Instance Variables in Objective-C

I'm having a hard time wrapping my head around this concept. I'll take the quote exactly from the book:

Class objects also inherit from the classes above them in the hierarchy. But because they don’t have instan开发者_开发知识库ce variables (only instances do), they inherit only methods.

Correct me if I'm wrong, but a class object would be this:

NSString *aString = [[NSString alloc]initWithString:@"abc.."];

The class object in this case is *aString -- am I correct so far?

The thing that confuses me is the second sentence in the quote above, "But because they don’t have instance variables (only instances do), they inherit only methods."

I thought that an object (in this case *aString) was the instance of the NSString class. The second sentence above is implying that an instance is something different. It's not making any sense to me.


You are incorrect.

NSString *aString = [[NSString alloc] initWithString:@"abc..."];

In this line, we have, from left-to-right:

  • A type: NSString *
  • A variable name: aString
  • an assignment
  • A Class: NSString
  • An invocation of a class method: +alloc
  • An invocation of an instance method on the return value of the class method: -initWithString:
  • An object being passed as a parameter to the instance method: @"abc..."

In Objective-C, a Class is actually a kind of object. You can interact with them in many of the same ways that you can instances, but since they are "classes", they cannot have instance variables (since instance variables, by definition, are only for instances). Classes only have methods. They inherit from other Classes, and this is how object inheritance is implemented.

For more information on this, check out this awesome blog post by Greg Parker: http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html


In ObjectiveC the classes themselves are objects.

In your example, aString is an NSString object BUT NSString is also an object, it's a class object.

Class object have methods declared like this for example

@interface MyClass : NSObject
{
}

+(void) myClassMethod;

@end

To call the myClassMethod method you type :

[MyClass myClassMethod];

But there is no static variable like in C++ or Java so the class object (here MyClass) can't contain variable but an instance of the class MyClass can have variable.

So to resume NSString is a class object and aString is an instance object of NSString.


In Objective-C, there are instances, which are the objects that you create and use, and there are (semi-hidden) objects which are class objects, and which are created by the compiler. The class object is where the methods for the class are stored; each instance holds only its own data (i.e., instance variables).

Bob * myBob = [[Bob alloc] init];

Here, myBob is an instance. Every instance has a reference back to its class object.1 When you call a method on an instance:

[myBob frogBlastTheVentCore];

the runtime goes and looks up the method in the class object, then uses the instance and the instance's data to perform the method. That's the basic organization of objects in Obj-C: instance objects hold data and have references to their class objects, which hold methods. There is only one class object per class; all instances of that class have a reference to the same class object.

A class (considered as a "type" rather than an object for a moment2) is said to inherit from another class:

@interface Bob : NSObject {
    NSColor * uniformColor;        
}
+ (BOOL) willShootAtPlayer;
- (void) frogBlastTheVentCore;
@end

@interface VacuBob : Bob {}
@end

Here, VacuBob is a subclass of Bob; any instance of VacuBob has its own uniformColor instance variable. Likewise, there is a class object VacuBob created by the compiler; it too inherits from Bob -- from the Bob class object. This means that the VacuBob class object also has the method willShootAtPlayer.

In the line you posted:

... aString = [NSString alloc] ...

the class object is actually NSString here. You are calling the class method named +[NSString alloc]3 (class methods being denoted by + rather than -4). When a class name is used as the receiver of a message (the first half of the bracketed expression), it refers to the class object5. In this case, then, both NSString and aString are objects; they are just two different kinds of objects; aString is an instance.

Dave DeLong linked to a good post on this (the diagram in particular pretty much lays everything out); for more info, you should also check out Matt Neuberg's description of "The Secret Life of Classes" in his iOS book. It describes the creation of class objects, their uses, and the other things that they do besides holding methods.


1This is the isa pointer: myBob->isa refers to the Bob class object.

2A variable referring to a class object has type Class. An instance object's type is its class. So the type of Bob is Class and the type of myBob is Bob * (that is, a pointer to an object, whose type is Bob). The distinction between the type of a variable and the type of an object may be cause some confusion here.

3The return value of alloc happens to be an instance of NSString, on which you call the instance method initWithString:

4Class methods parallel instance methods in that they are called with the class object itself as an argument. Since class objects have no data of their own, the use of class methods is perhaps more limited than other OO languages; class methods are most often used for vending instances.

5When it is used in the declaration of a variable: NSString * mySting;, it is the name of the type of the variable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜