-1

Consider following interfaces:

@interface Bar : NSObject

@end

@interface Foo : Bar

@end

What's the difference between...

@implementation Foo

- (id)init
{
    return [super init];
}

@end

... and...

@implementation Foo

- (id)init
{
    return [[Bar alloc] init];
}

@end

...?

EDIT: for clarification I am adding more code...

/* =============
 * GenericCell.h
 * =============
 */

// imports, etc.

typedef enum {
   GenericCellStyleFoo,
   GenericCellStyleBar
} GenericCellStyle;

@interface GenericCell : UITableViewCell

- (id)initWithStyle:(GenericCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;

@end

/* =============
 * GenericCell.m
 * =============
 */

// imports, etc.

@interface FooCell : GenericCell

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier;

@end

@interface BarCell : GenericCell

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier;

@end

@implementation FooCell

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    // *************************************************************************
    // This will actually call GenericCell's 'initWithStyle:reuseIdentifier:',
    // hence the "loop"!
    // *************************************************************************
    self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
    if (self) {
        // various subviews or whatever to make this cell so special...
    }
    return self;
}

@end

@implementation BarCell

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    // *************************************************************************
    // This will actually call GenericCell's 'initWithStyle:reuseIdentifier:',
    // hence the "loop"!
    // *************************************************************************
    self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
    if (self) {
        // various subviews or whatever to make this cell so special...
    }
    return self;
}

@end

@implementation GenericCell

// some useful code...

- (id)initWithStyle:(GenericCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (style == GenericCellStyleFoo) {
        return [[FooCell alloc] initWithReuseIdentifier:reuseIdentifier];
    }
    else if (style == GenericCellStyleBar) {
        return [[BarCell alloc] initWithReuseIdentifier:reuseIdentifier];
    }

    return nil; // doesn't really matter for sake of this example
}

// some useful code...

@end

/* =================================
 * SomeTableViewControllerInstance.m
 * =================================
 */

// imports, etc.

@implementation SomeTableViewControllerInstance

// some useful code...

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    GenericCellStyle style = [self styleDoesntMatterHowForRowAtIndexPath:indexPath];

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell;

    // dequeue and all that...

    if (cell == nil) {
        cell = [[GenericCell alloc] initWithStyle:style reuseIdentifier:CellIdentifier];
    }

    // set labels, or whatever...

    return cell;
}

// some useful code...

@end

// End of file
Ali
  • 1,396
  • 14
  • 37
  • Where did you see the second way used? It doesn't seem like it would be useful. – woz Aug 31 '12 at 17:28
  • I am in a situation where if someone calls init of a class Foo, internally I might actually create an object of type "FooSomething : Foo" or "FooSomeOtherThing : Foo" in different cases. Since both Foo* and Foo have "init" if you do [super init] inside either Foo* you will get your self into a loop. – Ali Aug 31 '12 at 17:32
  • For one thing, you're leaking in the second. – jscs Aug 31 '12 at 19:08
  • 2
    Mainly, the first will return a Foo object while the second will return a Bar object (and leak the created Foo). – Hot Licks Aug 31 '12 at 19:24
  • Exalted -- The logic you describe will result in an infinite recursion regardless. There must be some logic in your `init` that will decide to NOT create the inner object at some point in the recursion. – Hot Licks Sep 01 '12 at 12:07
  • Voring to close because you are asking for a code review, not for an explanation between super init and parent alloc init. – Jano Sep 02 '12 at 20:53
  • @Jano That's not true, although I am sorry. I couldn't make my self clear without it... – Ali Sep 02 '12 at 21:13
  • 1
    Instead of calling `alloc/initWithStyle`, call GenericCell `+newGenericCellFactory`, and put the logic you want in there. – Hot Licks Sep 02 '12 at 21:37

1 Answers1

1

When you use super, you aren't referring to a parent class. You are really referring to the object you are creating, in a way. See this question:

What exactly is super in Objective-C?

There's a lot of links and information in the answers that really explain it in detail.

Community
  • 1
  • 1
woz
  • 10,888
  • 3
  • 34
  • 64
  • Is there anything wrong if had to still call "self = [[ParentClass alloc] init]" if I had to break the loop? I know "[super init]" is the way to go, but I can't seem to break it otherwise. – Ali Aug 31 '12 at 17:47
  • I guess you could. I don't know why you would though. This article is kind of interesting, but note the update at the bottom: http://www.wilshipley.com/blog/2005/07/self-stupid-init.html – woz Aug 31 '12 at 17:53
  • I don't think I understand your issue with using `[super init]`. Why would it return a different object type depending on the situation? Can you post some code from your classes? – woz Aug 31 '12 at 17:59
  • 1
    @exalted -- What is this "loop" you want to "break"? – Hot Licks Sep 01 '12 at 03:14
  • @HotLicks I hope my new edit will clear things a little bit. – Ali Sep 02 '12 at 20:44