在iOS 8.4和9.3版本上,NSDate在小于5秒的模拟器上崩溃

时间:2016-05-20 10:17:15

标签: ios swift nsdate

我遇到一个奇怪的错误,我的应用程序将在比iPhone 5s更少的所有模拟器上崩溃。

首先,我尝试重置所有模拟器,但崩溃仍然存在。

代码

extension NSDate {

  func firstDayOfMonth() -> NSDate {
    let cal = NSCalendar.currentCalendar()
    let comp = cal.components([.Year, .Month], fromDate: self)

    // to 12pm
    comp.hour = 12
    comp.minute = 0
    comp.second = 0

    return cal.dateFromComponents(comp)!
  }


  func lastDayOfMonth() -> NSDate {
    let cal = NSCalendar.currentCalendar()
    let comp = NSDateComponents()

    comp.month = 1
    comp.day -= 1

    // to 12pm
    comp.hour = 12
    comp.minute = 0
    comp.second = 0

    return cal.dateByAddingComponents(comp, toDate: self.firstDayOfMonth()!, options: [])!
  }
}


错误

第二个函数中的最后一行代码:
cal.dateByAddingComponents(comp, toDate: self.firstDayOfMonth()!, options: [])! 在发生崩溃的设备上返回5828963-12-20 00:00:00 +0000


重现错误

在iPhone 4s(v8.4,v9.3)和iPhone 5(v8.4,v9.3)上运行时,我能够始终如一地重现此问题但是在操场上或在操场上不会出现错误iPhone 5s或iPhone 6 / 6s

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

请尝试这个替代日期数学

extension NSDate {

  func firstDayOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    var startDate : NSDate?
    calendar.rangeOfUnit(.Month, startDate: &startDate, interval: nil, forDate: self)
    let components = calendar.components([.Year, .Month, .Day], fromDate: startDate!)
    components.hour = 12
    return calendar.dateFromComponents(components)!
  }

  func lastDayOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    let dayRange = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self)
    let dayLength = dayRange.length
    let components = calendar.components([.Year, .Month, .Day], fromDate: self)
    components.day = dayLength
    components.hour = 12
    return calendar.dateFromComponents(components)!
  }
}

Swift 3

extension Date {

    func firstDateOfMonth() -> Date {

        let calendar = Calendar.current
        var startDate = Date()
        var interval : TimeInterval = 0
        _ = calendar.dateInterval(of:.month, start: &startDate, interval: &interval, for: self)
        return startDate
    }

    func lastDateOfMonth() -> Date {

        let calendar = Calendar.current
        let dayRange = calendar.range(of:.day, in: .month, for: self)!
        let dayLength = dayRange.upperBound
        var components = calendar.dateComponents([.year, .month, .day], from: self)
        components.day = dayLength
        return calendar.date(from:components)!
    }
}

将小时设置为12可能非常有用,特别是在巴西,其中一个夏令时跳过0:00到0:59。

答案 1 :(得分:1)

由于Integer溢出,可能会发生这种情况。 iPhone 5s及以上使用64-bit个处理器,其中使用32-bit。请查看此Apple文档,了解如何使用dateFromComponents ..

查找天数之间的差异

来自apple documentation ...

  

不要使用此方法来比较第二个差异,因为它会在32位平台上溢出NSInteger。

避免崩溃的可能解决方案

  • 尝试从日期比较中删除秒数。