سؤال

I am attempting to override the init method of a class so that initializing the object also initializes the ivar object:

-(id)init 
  {
    if (self = [super init])
    {
       someIVarObject = [SomeClass alloc] init];
    }
    return self;
  }

1) Would this code even work, and even so, is this solution discouraged?
2) Why is the if condition not == ? Is it an assignment? If so, why the if?

Sorry if this is obvious! >_<

هل كانت مفيدة؟

المحلول

Yes, it would work, and afaik it's still the way it should be done.

What it does is to call [super init] and allows it to do one of three things;

  • Return self (ie the same object self is already set to.
  • Return an entirely new object.
  • Return nil for failure.

The result is then assigned to self, which makes sure that the rest of the constructor operates on the correct object in case it changed. The if is there to catch the case where [super init] returned nil, in which case the rest of the constructor should be skipped.

نصائح أخرى

1) Here you are declaring a local variable someIVarObject. You should have declared this within the interface or implementation of your class in curly braces, and should then assign it as someIvarObject = .... An example:

@implementation MyClass {
    SomeClass *someIvarObject;
}

- (id)init
{
    if(self = [super init])
    {
        someIvarObject = [[SomeClass alloc] init];
    }
    return self;
}

@end

2) It is an assignment. There is a long history behind this idiom but it mostly comes down to handling the possibility that [super init] returns a different object than init was originally invoked upon.

This...

if(self = [super init])

will work, but it will give you a compiler warning (unless you've turned off this warning).

You can also suppress the warning by using double parenthesis:

if((self = [super init]))

My current preference:

self = [super init];
if(self)

You've got some typos, unbalanced brackets, and the thing you say is an ivar is not an ivar (you declare it inside the if, which makes its scope local to that block. You want to put instance variables in the {}s after your @implementation or @interface declarations). But yes, this is generally how this would work.

However, I'd take a hard look at whether you really need an ivar or not. I can't remember the last time I used one in my code. 99% of the situations I used to use them in, a @property is now a much better solution.

As an added benefit, @propertys synthesize their own getters and setters, (usually) obviating the need to write manual allocing boilerplate, thus making this question moot.

1) this code will work but this line:

SomeClass *someIVarObject = [SomeClass alloc] init];

makes a little sense. Declare SomeClass *someIVarObject in .h file and initialize it in init like this:

someIVarObject = [SomeClass alloc] init];

2) this line if (self = [super init]) is equivalent to:

self = [super init]; if (self != nil)

i.e. it ensures that init method of the base class has returned a proper value

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top