How to avoid rewriting Initializers in Swift?

| | August 8, 2015

With Objective-C I am initializing my classes like that:

SomeClass *anInstance = [SomeClass new]

anInstance.importantInt = 4;
anInstance.importantString = @"Vip";
anInstance.importantDelegate = self;

[anInstance initialize];

I am doing it like that to avoid rewriting my initializers or to avoid having multiple initializers with duplicated code during ongoing development of a class. I am calling -(void)initialize to do the setup of the instance.

This way I can use dot-notation to assign properties and simply add a new line if I need to add properties to the class later on.

To avoid adding -(void)initialize to every header I am doing this using an extension of NSObject or my own superclass or with protocols.

As I am now starting to work with swift I was asking myself if it still makes sense to do it in this “personal design pattern”. Are there concepts in swift that would allow me to easily add properties without rewriting initializers to assign external values?

I already read through the swift guide from Apple an took a deeper look into initialization of classes/structures but I really do not recognize any situation where these swift benefits could help me in my situation.

One Response to “How to avoid rewriting Initializers in Swift?”

  1. You shouldn’t be doing any initialization outside of a class’s initializers. Luckily, though, it’s easy to avoid repeating code. Cocoa has the notion of a “designated initializer”, which does all necessary initialization for a class; a class can have other initializers that defer to the designated initializer. In your case, your class would have a designated initializer that looks like this:

    - (id)initWithInt:(NSInteger)i string:(NSString *)s
    {
        if ((self = [super init])) {
            _importantInt = i;
            _importantString = [s copy];
        }
        return self;
    }
    

    And then it could have a “convenience initializer” that looks like this:

    - (id)init
    {
        return [self initWithInt:4 string:@"Vip"];
    }
    

    Thus, you can encapsulate initialization entirely within a class, without repeating code.

    Swift operates on a similar principle. It allows you to have several initializers. Some can be “designated initializers”, and some can be “convenience initializers”. A designated initializer generally does all of the initialization for a class. In your case, it would look something like this:

    init(withInt i: Int, s: String) {
        self.importantInt = i
        self.importantString = s
    }
    

    The convenience initializer would look something like this:

    convenience init() {
        self.init(withInt: 4, string: "Vip")
    }
    

    As in Objective-C, initialization is still done entirely within the class, without duplication of code.

Leave a Reply