Did not understand process of initialize in swift

2019-05-29 10:54发布

问题:

I am learning Swfit and i start studied from below link
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html

I have question regarding Initialization in swift.

What i understand is as below

1] It works like a constructor for swift classes.
2] We have to initialize all properties in it.
3] We have to call init() method of super class.
4] Before calling init() we have to initialize each and every property.
5] We can use any member or method of super classes after initialize it.

On the bases of above 5 points I create a classes.
but having a problem because of point 3,4 and 5.

Classes

/*
AdminManagmentSystem
- Some class which will consume lots of memory during init
*/
class AdminManagmentSystem {

    var adminKey : String
    init(key:String)
    {
        self.adminKey = key;
        println("Consume lots of memory");
    }
}

/*
Person
- A base class which can create key.
*/
class Person {

    // Some property which will user to create private key.
    private var privateKey : String = "private"
    init()
    {
        privateKey = "private";
    }

    // function which will calculate key (Comman for all person type)
    private  func calculatekey() -> NSString
    {
        return self.privateKey + " key";
    }
}

/*
Admin
- A sub class which have object of AdminManagmentSystem
*/
class Admin : Person {

    // Constant variable
    let adminmanagmennt : AdminManagmentSystem

    override init()
    {
        self.adminmanagmennt = AdminManagmentSystem(key: ""); // Line1 : Consume lots of memory
        super.init(); // Line2 : its compalsurry to call super.init
        var adminKey = super.calculatekey(); // Line3 : We can use any member or method of supper after callign init().
        self.adminmanagmennt = AdminManagmentSystem(key: adminKey); // Line4 : Again consume lots of memory
    }
}


Download project
https://www.dropbox.com/s/afohuxpxxkl5b3c/understandInheritance.zip?dl=0


Problem
In Line1 and Line4 i have to create object of AdminManagmentSystem which consume a lot memory.

Question
1] Why swift make it compulsory to initialize each and every property before calling super.init()?
2] If I make my property constant why swift allow me to initialize it more then once in init method ?
3] Why i must have to write override keyword before init() ?

回答1:

In answer to 1 -

From the Swift Programming Language -

“As mentioned above, the memory for an object is only considered fully initialized once the initial state of all of its stored properties is known. In order for this rule to be satisfied, a designated initializer must make sure that all its own properties are initialized before it hands off up the chain.”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/au/jEUH0.l

So, until the object is fully initialised, the object is in an undefined state which may be "unsafe", so Swift requires all properties are initialised in phase 1.

In answer to 2

An initialiser function is a special case - its job is to set the object to its initial state, so you can modify 'constant' properties as the object is still in the process of being created -

“You can modify the value of a constant property at any point during initialization, as long as it is set to a definite value by the time initialization finishes.”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/au/jEUH0.l

In answer to 3, because you are overriding a method with the same signature as the super class (the no argument init function). The override keyword indicates to the compiler that you know what you are doing. If the compiler silently let you re-declare a super class method you may not realise that you are doing it and get unexpected results.

In answer to the question regarding the consumption of memory, ARC will quickly reclaim the memory that was allocated for the first instance of the object. If this is a performance issue then it is fairly simple to refactor the AdminManagmentSystem class so that there is a function to reset the key on an existing instance -

class Admin : Person {

    // Constant variable
    let adminmanagmennt : AdminManagmentSystem

    override init()
    {
        self.adminmanagmennt = AdminManagmentSystem(key: ""); // Line1 : Consume lots of memory
        super.init(); // Line2 : its compalsurry to call super.init
        var adminKey = super.calculatekey(); // Line3 : We can use any member or method of supper after callign init().
        self.adminmanagmennt.key=adminKey;  // You can use a property observer function if a simple assignment isn't enough
    }
}