NSDate 在版本 iOS 8.4 和 9.3 的模拟器上崩溃不到 5 秒
NSDate crashing on simulators less than 5s on versions iOS 8.4 and 9.3
我有一个奇怪的错误,我的应用程序将在所有模拟器上崩溃少于 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: [])!
returns 5828963-12-20 00:00:00 +0000
在发生崩溃的设备上。
重现错误
当 运行 在 iPhone 4s(v8.4、v9.3)和 iPhone 5(v8.4、v9)上时,我能够始终如一地重现该问题.3) 但是错误不会发生在操场上或 iPhone 5s 或 iPhone 6/6s
如有任何帮助,我们将不胜感激。
这可能是由于整数溢出造成的。 iPhone 5s
及以上使用 64-bit
处理器,而以下使用 32-bit
处理器。请检查此苹果文档,了解使用 dateFromComponents
..
找出天数之间的差异
Do not use this method for comparing second differences because it overflows NSInteger on 32-bit platforms.
避免崩溃的可能解决方案
- 尝试从日期比较中删除秒数。
请试试这个替代日期数学
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。
我有一个奇怪的错误,我的应用程序将在所有模拟器上崩溃少于 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: [])!
returns 5828963-12-20 00:00:00 +0000
在发生崩溃的设备上。
重现错误
当 运行 在 iPhone 4s(v8.4、v9.3)和 iPhone 5(v8.4、v9)上时,我能够始终如一地重现该问题.3) 但是错误不会发生在操场上或 iPhone 5s 或 iPhone 6/6s
如有任何帮助,我们将不胜感激。
这可能是由于整数溢出造成的。 iPhone 5s
及以上使用 64-bit
处理器,而以下使用 32-bit
处理器。请检查此苹果文档,了解使用 dateFromComponents
..
Do not use this method for comparing second differences because it overflows NSInteger on 32-bit platforms.
避免崩溃的可能解决方案
- 尝试从日期比较中删除秒数。
请试试这个替代日期数学
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。