views:

50

answers:

3

These are fairly simplistic questions, but something that I wanted to get right in my head before continuing...

@interface BasicTire : NSObject {
}
@end

@interface SnowTire : BasicTire {
}
@end
  1. When you call [SnowTire init] the included [super init] calls [BasicTire init] which in turn calls [NSObject init]? (i.e. a cascade running up to the parent/superclass.

  2. When you [SnowTire alloc] you are creating a single new object, that includes the the functionality of its superClass. Am I right in thinking your not creating multiple objects that are linked in some fashion (i.e. SnowTire > BasicTire > NSObject).

Just wanted to check ...

gary

+3  A: 
  1. Yes, normally initializers call superclass initializers. This is done explicitly in the implementation of the init method. While it's possible to call other initializers of the same class or its superclass, it's necessary to make sure that the "designated initializer" always get's called.
    If an object does not implement init (or the initializer in question), the one from the superclass is called (like with any other method). This is not seldom, since in Objectve-C instance variables are always initialized to zero (in alloc) and so it's often not necessary to implement a specialized init.

  2. alloc just allocates memory and sets the "isa pointer" of an object which determines an objects class. What you get from it is one uninitialized object (not a linked list) which has room for all of its instance variables (including super classes).

Nikolai Ruhe
Perfect, thank you Nikolai
fuzzygoat
+2  A: 
  1. Yes. Each initializer must call the designated initializer for the superclass, all the way up to NSObject. It is also important that each initializer assigns the the result from the super initializer to self. Since an initializer is not required to return the same instance that you send the initialize message to.

  2. Yes. alloc initialized enough memory on the heap for the objects instance variables, and clears this memory with zeros. This way all pointers will be nil, booleans false, etc. And then it sets the isa pointer to the class of the new object.

PeyloW
+1  A: 

When you call [SnowTire init] the included [super init] calls [BasicTire init] which in turn calls [NSObject init]? (i.e. a cascade running up to the parent/superclass.

You implement both -[SnowTire init] and -[BasicTire init], so you can just look at your implementations to see that:

  1. Your -[SnowTire init] uses [super init] to call -[BasicTire init].
  2. Your -[BasicTire init] uses [super init] to call -[NSObject init].

[super init] always calls the next available implementation, even if it's not in your immediate superclass. If you don't implement -[BasicTire init], then the [super init] expression in -[SnowTire init] will call -[NSObject init]. That's fine, because you apparently decided that a BasicTire doesn't need any initialization. (If it does, then your omission of -[BasicTire init] was a mistake.)

When you [SnowTire alloc] you are creating a single new object, that includes the the functionality of its superClass. Am I right in thinking your not creating multiple objects that are linked in some fashion (i.e. SnowTire > BasicTire > NSObject).

Yes. Every object has a class (in a variable named isa, as in “this instance is a SnowTire”), and every class has a superclass and a metaclass. -alloc and -init, like all Objective-C methods and C functions, each only return one thing—in this case, one instance with one class.

So, for example, when you send a gripTheSnow message to your snow tire, it uses SnowTire's implementation of that method. If you send a retain message, well, you didn't implement retain in SnowTire and you didn't implement it in BasicTire, so it uses NSObject's implementation. The runtime searches, starting from the object's class (in this example, SnowTire), in a straight line up the class hierarchy, ending at a root class such as NSObject.

Peter Hosey