避免重新实例化Swift静态计算属性

时间:2018-01-29 05:09:33

标签: swift nscalendar

我的课程需要GMT日历来完成许多公共职能。我简化了这个类为了演示而执行的功能。

class GMTDate {
    private var date: Date

    init(dateInGMTDay date: Date) {
        self.date = GMTDate.gmtCal.startOfDay(for: date)
    }

    func daysInMonth() -> Int {
        return GMTDate.gmtCal.range(of: .day, in: .month, for: self.date)!.count
    }

    // Several other functions that use gmtCal

    private static var gmtCal: Int {
        var cal = Calendar(identifier: .gregorian)
        cal.timeZone = self.gmtTimeZone
        return cal
    }
}

我目前正在这样做的方式,每次在Calendar的实例上调用函数时,都会创建一个新的GMTDate。这是不可取的,因为如果多次调用这些函数,它们将乘以Calendar的实例化时间运行这些函数所需的时间。我更喜欢在内存中创建一个实例,等待使用。

另一个选择是使gmtCal成为一个懒惰的实例化变量,并存储一个实例化的副本。像这样:

private var _gmtCal: Calendar?

private var gmtCal: Calendar {
    if let cal = _gmtCal {
        return cal
    }
    var cal = Calendar(identifier: .gregorian)
    cal.timeZone = GMTDate.gmtTimeZone
    _gmtCal = cal
    return cal
}

但是,这需要每Calendar次存储一个完整的GMTDate,我不想这样做,因为我可能会创建大量的GMTDate和我&# 39; d不希望将每个GMTDate的内存占用量增加Calendar的大小。

还有其他选择吗?如果可能的话,我只想实例化Calendar的一个副本用于此类。

1 个答案:

答案 0 :(得分:0)

是。虽然您无法使用private static lazy懒惰地实例化一个惰性静态变量,但您可以按如下方式手动实例化它:

private static var _gmtCal: Calendar?
private static var gmtCal: Calendar {
    if let cal = GMTDate._gmtCal {
        return cal
    }
    var cal = Calendar(identifier: .gregorian)
    cal.timeZone = GMTDate.gmtTimeZone
    GMTDate._gmtCal = cal
    return cal
}