简体   繁体   中英

Swift - How to initialize a default value for NSDate property?

I have a simple class definition:

class Course{

    var date:NSDate

    init(){

    }
}

In c#, for example, when creating this class, the date property will have the default of DateTime.MinValue.

  • I don't want to make this an NSDate? because by my business logic this property is a must, and every course has a date . (Setting to NSDate? will imply that a course can exists without a Date)

  • I don't want to set it to Now because it is misleading. Now could be a valid value, that came from other part of my business logic.

How can I do the same in swift?

If all Courses need valid dates, why do you want to create Courses that don't have a real date? Get rid of init() and create a designated initializer.

class Course{
    let date: NSDate

    init(date: NSDate) {
        self.date = date
    }
}

If you insist on having these weird "not real dates" you can use distantPast() .

class Course{
    var date: NSDate

    init() {
        self.date = NSDate.distantPast() as NSDate
    }
}

You can create an extension to NSDate like so:

extension NSDate
{
    class func minimumDate() -> NSDate
    {
        let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
        return calendar.dateWithEra(1, year: 1, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)!
    }
}

This will allow you to instantiate a new NSDate with the similar 1/1/0001 00:00:00 timestamp:

let myDate = NSDate.minimumDate()

Swift also has a null-coalesce operator ( ?? ) which allows you do to something like this in your initializer:

class Widget
{
    var dateCreated : NSDate

    init(dateCreated: NSDate?)
    {
        self.dateCreated = dateCreated ?? NSDate.minimumDate()
    }
}

If you always initialize date in the init method (which, if, as you say, it must have a date), then the following is fine:

class Course {    
    var date: Date          // if Swift 2 we’d use `NSDate`, but in Swift 3 and later, we’d use `Date`

    init() {
        date = ... // set it to some reasonable, default value
    }
}

Or, if there is no reasonable, default value, you'd specify an initializer where you supply the value:

class Course {    
    var date: Date

    init(date: Date) {
        self.date = date
    }
}

If, however, there are reasons why you cannot specify the value when the object is instantiated and can only set date at some later point, but it should always have a value from that point forward, you would use an implicitly unwrapped optional. As the documentation for implicitly unwrapped optionals says:

Sometimes it is clear from a program's structure that an optional will always have a value, after that value is first set. In these cases, it is useful to remove the need to check and unwrap the optional's value every time it is accessed, because it can be safely assumed to have a value all of the time.

These kinds of optionals are defined as implicitly unwrapped optionals. You write an implicitly unwrapped optional by placing an exclamation mark ( String! ) rather than a question mark ( String? ) after the type that you want to make optional.

Thus, you would have

class Course {
    var date: Date!

    init() {
        // the `date` is not necessarily set here, but once it is set, it shouldn't be `nil` thereafter
    }
}

Yes, technically, with implicitly unwrapped optional, date could be nil , but the practice is that if it might initially be nil , but once set, it will never be nil again, you would use implicitly wrapped optional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM