在我的iOS项目中,我使用一个常规的
当某些属性被设置时,该单元格会接收一些属性,并对该单元格执行一些UI更新。
但是当我滚动时,我感觉到轻微的卡顿,但我不知道如何改进我的代码以使其运行更顺畅。
我已经运行了Intruments并运行了时间分析器,当出现这些延迟时,主线程CPU使用率达到100%,如您所见: 追踪仪器使用百分比得出以下结论:
在我的
UICollectionView
和自定义单元格。当某些属性被设置时,该单元格会接收一些属性,并对该单元格执行一些UI更新。
但是当我滚动时,我感觉到轻微的卡顿,但我不知道如何改进我的代码以使其运行更顺畅。
我已经运行了Intruments并运行了时间分析器,当出现这些延迟时,主线程CPU使用率达到100%,如您所见: 追踪仪器使用百分比得出以下结论:
进一步追踪 png_read_IDAT_data
在我的
UICollectionViewController cellForItem(:_)
方法中:override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: homeCellId, for: indexPath) as! HomePostCollectionViewCell
cell.post = self.posts[indexPath.item]
cell.delegate = self
cell.layer.cornerRadius = 5
cell.layer.borderWidth = 0.7
cell.layer.borderColor = UIColor.rgb(red: 204, green: 204, blue: 204).cgColor
cell.layer.masksToBounds = true
return cell
}
每当post
变量被设置时,我会在我的UICollectionViewCell
内执行以下UI更新:
public var post: Post? {
didSet {
guard let post = self.post else { return }
userProfileImageView.image = post.user.profileImage
nameLabel.text = post.user.name
titleTextView.text = post.title
creationDateLabel.text = post.creationDate.timeAgoDisplay()
thumbnailImageView.image = post.thumbnail
if backgroundImageOffset != nil {
setBackgroundImageOffset(imageOffset: backgroundImageOffset)
} else {
setBackgroundImageOffset(imageOffset: CGPoint.zero)
}
}
}
你能帮我追踪问题并改进它吗?
谢谢。
编辑
我已经注释掉了cell.post=
这一行,通过这样做,主线程CPU使用率降低到约10%,因此可以确定问题出现在post { didSet {} }
构造函数内部。
你能看到有什么有用的改进吗?
编辑2
根据要求,这是timeAgoDisplay()
函数的代码
func timeAgoDisplay() -> String {
let secondsAgo = Int(Date().timeIntervalSince(self))
let minute = 60
let hour = 60 * minute
let day = 24 * hour
let week = 7 * day
let month = 4 * week
let quotient: Int
let unit: String
if secondsAgo < minute {
quotient = secondsAgo
unit = "second"
} else if secondsAgo < hour {
quotient = secondsAgo / minute
unit = "min"
} else if secondsAgo < day {
quotient = secondsAgo / hour
unit = "hour"
} else if secondsAgo < week {
quotient = secondsAgo / day
unit = "day"
} else if secondsAgo < month {
quotient = secondsAgo / week
unit = "week"
} else {
quotient = secondsAgo / month
unit = "month"
}
return "\(quotient) \(unit)\(quotient == 1 ? "" : "s") ago"
}
cell.layer.stuff
方法中只能在单元格初始化方法(awakeFromNib()
或init(frame:style)
)中执行一次。此外,我认为timeAgoDisplay()
方法也可以进行优化。这是什么代码?你每次都要在其中初始化一个新的dateFormatter吗?如果是,请每次使用相同的dateFormatter(创建一个静态/单例)。这些是小的改进,也许与你整个问题无关。 - LarmeDate() 扩展函数
。 - Ivan CantarinoDateFormatter
。请注释与setBackgroundImageOffset(imageOffset:)
和/或userProfileImageView.image =
相关的内容。检查一下是否有改进。这些图片的尺寸是多少? - Larme