动态改变 cell.update 日期函数?
Dynamically changing cell.update Date function?
我对这一切都是新手,请原谅我的无知!我有一个 Table View
每次打开场景时我都会调用一个单元格更新方法(它按日期排序)。我正在尝试根据上次编辑对象的时间动态显示不同的日期格式。示例:如果日期是今天则显示时间,如果日期是昨天则显示 "Yesterday" 等。我的问题是 - 编写此代码的最佳方式是什么,并在我的 cell.update 调用中调用以下函数内存密集型?我怎样才能写得更好?任何帮助将不胜感激!
func update(with fitnessInfo: Fitness) {
if let date = fitnessInfo.dateEdited as Date? {
let today = Calendar.current.isDateInToday(date)
let yesterdayFunc = Calendar.current.isDateInYesterday(date)
let yesterday = date.addingTimeInterval(172800)
let withinSevenDays = date.addingTimeInterval(604800)
let dateFormatter = DateFormatter()
func setdate(_ dateFormatter: DateFormatter) {
let convertedDate = dateFormatter.string(from: date)
fitnessDateLabel.text = convertedDate
}
if today == true {
dateFormatter.dateFormat = "h:mm a"
setdate(dateFormatter)
} else if yesterdayFunc == true {
fitnessDateLabel.text = "Yesterday"
} else {
switch date {
case yesterday...withinSevenDays:
dateFormatter.dateFormat = "EEEE"
setdate(dateFormatter)
default:
dateFormatter.dateFormat = "MMMM dd, yyyy"
setdate(dateFormatter)
}
}
}
这是从中调用的 Table 视图函数 (cellForRowAt)。
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “fitnessCell", for: indexPath) as! FitnessTableViewCell
let fitnessInfo = fetchedRC.object(at: indexPath)
cell.update(with: fitnessInfo)
return cell
}
- 如果代码有效,那一定不错。
- 在任何性能优化之前编写单元测试和性能测试是个好主意。所以您会看到您的更改不会影响结果并提高性能。您还可以使用 Xcode 工具来了解您的代码究竟如何使用 CPU 和内存,方法是单击 Product->Profile 和 select Time profile and Allocations 工具。不要忘记性能优化通常是内存和 CPU 使用之间的权衡。
您应该将逻辑与表示分开。所以你可以编写单元测试。您也可以静态保留 DateFrommater 而不是每次绘制单元格时都初始化它。这是一个如何完成的示例:
final class DateMapper {
static let todayDateFormatter = DateFormatter()
static let lastWeekAgoDateFormatter = DateFormatter()
static let moreThanWeekAgoDateFormatter = DateFormatter()
let today: Date
let currentCalendar = Calendar.current
init(today: Date) {
self.today = today
DateMapper.todayDateFormatter.dateFormat = "h:mm a"
DateMapper.lastWeekAgoDateFormatter.dateFormat = "EEEE"
DateMapper.moreThanWeekAgoDateFormatter.dateFormat = "MMMM dd, yyyy"
}
func formattedDate(date: Date) -> String {
guard let totalDays = currentCalendar.dateComponents([.day], from: date, to: today).day else {
return ""
}
switch totalDays {
case 0:
return DateMapper.todayDateFormatter.string(from: date)
case 1:
return "Yesterday"
case 2...7:
return DateMapper.lastWeekAgoDateFormatter.string(from: date)
default:
return DateMapper.moreThanWeekAgoDateFormatter.string(from: date)
}
}
}
这个 class 可以像这样在你的更新方法中使用:
func update(with fitnessInfo: Fitness) {
let dateMapper = DateMapper(today: Date())
fitnessDateLabel.text = dateMapper.formattedDate(date: fitnessInfo.dateEdited)
}
或者您可以在 ViewController 处保留 DateMapper 并直接在 cellForRowAt 处使用它。
这个class可以用单元测试覆盖:
class ExampleTests: XCTestCase {
var dateMapper: DateMapper {
let todayStub = dateStubByComponents(year: 2019, month: 5, day: 4, hour: 12)
return DateMapper(today: todayStub)
}
func testTodayDate() {
// arrange
let todayStub = dateStubByComponents(year: 2019, month: 5, day: 4, hour: 11)
// act
let result = dateMapper.formattedDate(date: todayStub)
// assert
XCTAssertEqual(result, "11:00 AM")
}
func testYestadayDate() {
// arrange
let yesterdayStub = dateStubByComponents(year: 2019, month: 5, day: 3, hour: 0)
// act
let result = dateMapper.formattedDate(date: yesterdayStub)
// assert
XCTAssertEqual(result, "Yesterday")
}
func testLastWeekDate() {
// arrange
let lastWeekStub = dateStubByComponents(year: 2019, month: 5, day: 2, hour: 0)
// act
let result = dateMapper.formattedDate(date: lastWeekStub)
// assert
XCTAssertEqual(result, "Thursday")
}
func testPerformanceExample() {
let lastWeekStub = dateStubByComponents(year: 2019, month: 5, day: 2, hour: 0)
self.measure {
_ = dateMapper.formattedDate(date: lastWeekStub)
}
}
// MARK: Private
private func dateStubByComponents(year: Int, month: Int, day: Int, hour: Int) -> Date {
var dateStubComponents = DateComponents()
dateStubComponents.year = year
dateStubComponents.month = month
dateStubComponents.day = day
dateStubComponents.hour = hour
guard let dateStub = Calendar.current.date(from: dateStubComponents) else { fatalError("Date must be valid") }
return dateStub
}
}
在控制台,您将看到将 Date 转换为 String 需要多长时间:
values: [0.000922, 0.000063, 0.000041, 0.000038, 0.000036, 0.000035,
0.000035, 0.000036, 0.000043, 0.000027]
我对这一切都是新手,请原谅我的无知!我有一个 Table View
每次打开场景时我都会调用一个单元格更新方法(它按日期排序)。我正在尝试根据上次编辑对象的时间动态显示不同的日期格式。示例:如果日期是今天则显示时间,如果日期是昨天则显示 "Yesterday" 等。我的问题是 - 编写此代码的最佳方式是什么,并在我的 cell.update 调用中调用以下函数内存密集型?我怎样才能写得更好?任何帮助将不胜感激!
func update(with fitnessInfo: Fitness) {
if let date = fitnessInfo.dateEdited as Date? {
let today = Calendar.current.isDateInToday(date)
let yesterdayFunc = Calendar.current.isDateInYesterday(date)
let yesterday = date.addingTimeInterval(172800)
let withinSevenDays = date.addingTimeInterval(604800)
let dateFormatter = DateFormatter()
func setdate(_ dateFormatter: DateFormatter) {
let convertedDate = dateFormatter.string(from: date)
fitnessDateLabel.text = convertedDate
}
if today == true {
dateFormatter.dateFormat = "h:mm a"
setdate(dateFormatter)
} else if yesterdayFunc == true {
fitnessDateLabel.text = "Yesterday"
} else {
switch date {
case yesterday...withinSevenDays:
dateFormatter.dateFormat = "EEEE"
setdate(dateFormatter)
default:
dateFormatter.dateFormat = "MMMM dd, yyyy"
setdate(dateFormatter)
}
}
}
这是从中调用的 Table 视图函数 (cellForRowAt)。
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “fitnessCell", for: indexPath) as! FitnessTableViewCell
let fitnessInfo = fetchedRC.object(at: indexPath)
cell.update(with: fitnessInfo)
return cell
}
- 如果代码有效,那一定不错。
- 在任何性能优化之前编写单元测试和性能测试是个好主意。所以您会看到您的更改不会影响结果并提高性能。您还可以使用 Xcode 工具来了解您的代码究竟如何使用 CPU 和内存,方法是单击 Product->Profile 和 select Time profile and Allocations 工具。不要忘记性能优化通常是内存和 CPU 使用之间的权衡。
您应该将逻辑与表示分开。所以你可以编写单元测试。您也可以静态保留 DateFrommater 而不是每次绘制单元格时都初始化它。这是一个如何完成的示例:
final class DateMapper { static let todayDateFormatter = DateFormatter() static let lastWeekAgoDateFormatter = DateFormatter() static let moreThanWeekAgoDateFormatter = DateFormatter() let today: Date let currentCalendar = Calendar.current init(today: Date) { self.today = today DateMapper.todayDateFormatter.dateFormat = "h:mm a" DateMapper.lastWeekAgoDateFormatter.dateFormat = "EEEE" DateMapper.moreThanWeekAgoDateFormatter.dateFormat = "MMMM dd, yyyy" } func formattedDate(date: Date) -> String { guard let totalDays = currentCalendar.dateComponents([.day], from: date, to: today).day else { return "" } switch totalDays { case 0: return DateMapper.todayDateFormatter.string(from: date) case 1: return "Yesterday" case 2...7: return DateMapper.lastWeekAgoDateFormatter.string(from: date) default: return DateMapper.moreThanWeekAgoDateFormatter.string(from: date) } } }
这个 class 可以像这样在你的更新方法中使用:
func update(with fitnessInfo: Fitness) {
let dateMapper = DateMapper(today: Date())
fitnessDateLabel.text = dateMapper.formattedDate(date: fitnessInfo.dateEdited)
}
或者您可以在 ViewController 处保留 DateMapper 并直接在 cellForRowAt 处使用它。
这个class可以用单元测试覆盖:
class ExampleTests: XCTestCase { var dateMapper: DateMapper { let todayStub = dateStubByComponents(year: 2019, month: 5, day: 4, hour: 12) return DateMapper(today: todayStub) } func testTodayDate() { // arrange let todayStub = dateStubByComponents(year: 2019, month: 5, day: 4, hour: 11) // act let result = dateMapper.formattedDate(date: todayStub) // assert XCTAssertEqual(result, "11:00 AM") } func testYestadayDate() { // arrange let yesterdayStub = dateStubByComponents(year: 2019, month: 5, day: 3, hour: 0) // act let result = dateMapper.formattedDate(date: yesterdayStub) // assert XCTAssertEqual(result, "Yesterday") } func testLastWeekDate() { // arrange let lastWeekStub = dateStubByComponents(year: 2019, month: 5, day: 2, hour: 0) // act let result = dateMapper.formattedDate(date: lastWeekStub) // assert XCTAssertEqual(result, "Thursday") } func testPerformanceExample() { let lastWeekStub = dateStubByComponents(year: 2019, month: 5, day: 2, hour: 0) self.measure { _ = dateMapper.formattedDate(date: lastWeekStub) } } // MARK: Private private func dateStubByComponents(year: Int, month: Int, day: Int, hour: Int) -> Date { var dateStubComponents = DateComponents() dateStubComponents.year = year dateStubComponents.month = month dateStubComponents.day = day dateStubComponents.hour = hour guard let dateStub = Calendar.current.date(from: dateStubComponents) else { fatalError("Date must be valid") } return dateStub } }
在控制台,您将看到将 Date 转换为 String 需要多长时间:
values: [0.000922, 0.000063, 0.000041, 0.000038, 0.000036, 0.000035, 0.000035, 0.000036, 0.000043, 0.000027]