Alex
Alex

Reputation: 3981

Static in ObjC vs Static in Swift

I'm trying to instantiate a DateFormatter only once for the class, so I don't waste a bunch of computing time doing it for every instance. In Obj-C I lazily instantiate a static property to accomplish this. I'm trying to figure out how to do this in Swift and most of the explanations I've read don't exactly answer this question.

In Obj-C:

- (NSDateFormatter *)dateFormatter {
    static NSDateFormatter *dateFormatter = nil;
    if (!dateFormatter) {
        dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateStyle = NSDateFormatterMediumStyle;
    }
    return dateFormatter;
}

Swift translation?

static var dateFormatter: DateFormatter {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    return dateFormatter
}

Upvotes: 1

Views: 323

Answers (3)

Paulw11
Paulw11

Reputation: 114975

Further to the answer by @CodeDifferent, you might want to wrap the static in a class var as this will allow you to override the date formatter in a subclass:

class MyClass {

    fileprivate static let mediumDateFormatter: DateFormatter = {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    return dateFormatter
    }()

    class var dateFormatter: DateFormatter  {
       return mediumDateFormatter
    }
}

class MyOtherClass: MyClass {

    fileprivate static let shortDateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .short
        return dateFormatter
    }()

   override class var dateFormatter: DateFormatter  {
        return shortDateFormatter
    }      
}

Upvotes: 0

vadian
vadian

Reputation: 285150

A lazy initialized static constant without using self in Swift is

static let dateFormatter: DateFormatter = {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    return dateFormatter
}()

The same code (without static) as instance property is also a constant but won't be initialized lazily.

However the static keyword in the ObjC code is a bit misleading. The 1:1 equivalent to the ObjC code is

lazy var dateFormatter: DateFormatter = {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    return dateFormatter
}()

The variable is initialized lazily but is an instance property.

Upvotes: 2

Code Different
Code Different

Reputation: 93181

You need to declare the static variable at the class level:

class MyClass {
    static var dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = DateFormatter.Style.medium
        return dateFormatter
    }()
}

Upvotes: 3

Related Questions