What is the best way to initialize an object?

I have been using Objective-C for several years, but I'm still not sure how to initialize the object. Our problem is as follows:

-(id)init { self = [super init]; if (self) { self.backgroundColor = [UIColor blueColor]; self.textColor = [UIColor greenColor]; } return self; } -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor yellowColor]; } return self; } 

How to initialize it the same in both methods means either copying or pasting coding (huge no, it causes endless problems due to human error, such as values ​​that are different, as in the example above) or a new method:

 -(id)init { self = [super init]; if (self) { [self initialSetup]; } return self; } -(id)initialSetup { self.backgroundColor = [UIColor blueColor]; self.textColor = [UIColor greenColor]; } 

In this case, the problem arises that if the subclass has an initialSetup method, calling the superclass [self initialSetup] calls the initialSetup subclass and thus ignores the entire superclass setting. You can get around this by adding a class name each time, such as initialSetupTextField .

It seems pretty dirty. This is just to initialize the object. How is everyone doing this?

+7
ios objective-c
source share
3 answers

Each class must have a designated initializer; one true version of the init... method, which must always be called in order to properly initialize the class (like Matt states).

However, this does not completely solve the problem in that the class can also support instantiation through unarchival, which runs in the same “where I posed the problem with general initialization” in your question.

As a rule, I create a method such as:

 - (void)commonInit { ... common initialization goop goes here ... } 

And then first call it from the designated initializers and / or initWithCoder:

Yes, a little messy, but little can be done about it.

General clutter reduction strategy:

• provide very few initializers; perhaps init + one initializer with all possible arguments for other configurations.

• Assign the super initializer as the DI and execute any additional initializers through it. When subclassing where you have a more specific DI (see UIView initWithFrame: , override super DI to call [self initFancy:...] , which then calls [super initThroughSupersDI] .

+9
source share

You are missing the concept of a designated initializer . You write one init method that does a heavy lift. All other initializers simply call the assigned initializer. Your example would look like this:

 -(id)init { return [self initWithFrame:CGRectZero]; } -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor yellowColor]; } return self; } 
+8
source share

... each time adding a class name, e.g. -initialSetupTextField

Yes, that’s it, or you can create a C function for your private instance initialization procedure - when the designated initializer is not enough. I use a different naming scheme from you, but as long as you use an agreement that avoids collision, then you are kind. I mention this because the method in your example may be confusing for getter.

Another thing I'm doing is to return a value from this routine, which indicates whether there was an error (i.e. nil should be returned).

+1
source share

All Articles