Pasakok apie invalidacijų naudojimo optimizavimą iOS kūrime.
sobes.tech AI
Atsakymas iš AI
Naudojimas setNeedsDisplay() ir setNeedsLayout(). setNeedsDisplay() planuoja perpiešimą vaizde, o setNeedsLayout() planuoja vaizdų išdėstymo atnaujinimą. Abi funkcijos neįvykdo atnaujinimo iš karto, o įtraukia jas į eilę kitam naudotojo sąsajos atnaujinimo ciklui. Tai leidžia sistemai sujungti kelis atnaujinimo užklausimus į vieną praeitį, sumažinant išlaidas.
Naudojimas CALayer optimizacijai piešimui. CALayer yra lengvas objektas, kuris valdo vizualinį turinį, bet neapdoroja įvykių. Sluoksnių piešimas dažnai vyksta už pagrindinio srauto, tai pagerina našumą. Sluoksnio savybės, tokios kaip opacity, transform ir backgroundColor, gali būti animuojamos be poreikio perpiešti visą vaizdų hierarchiją.
Mažinti perpiešimo zonas. iOS sistema stengiasi perpiešti tik tą ekrano dalį, kuri pasikeitė. Tačiau, jei setNeedsDisplay() iškvietimas yra didesniame plote arba nepermatomame vaizde, sistema gali būti priversta perpiešti didesnę ekrano dalį. Reikėtų stengtis iškviesti setNeedsDisplay() mažiausiame įmanomame vaizde, kuris tikrai turi būti atnaujintas.
Turinio vėlinis įkėlimas. Jei vaizdas turi daug turinio (pavyzdžiui, ilgą sąrašą UITableView ar UICollectionView), nereikėtų iš karto piešti viso turinio. Vietoj to, įkelkite ir rodykite turinį pagal jo pasirodymą ekrane (on-demand). Tai žymiai sumažina sistemos apkrovą pradiniame įkėlimo ir slinkimo metu.
Kaušų naudojimas. Jei tam tikros dalies piešimas užima daug laiko ir retai keičiasi, galima rezultatus įrašyti į cache (pavyzdžiui, kaip UIImage). Sekančiuose piešimuose paprasčiausiai naudokite įrašytą vaizdą vietoje pakartotinio piešimo.
Pavyzdys naudojant setNeedsDisplay():
class MyView: UIView {
override func draw(_ rect: CGRect) {
// Piešimo kodas
}
func updateContent() {
// Duomenų keitimas, kuris veikia piešimą
setNeedsDisplay() // Planavimas perpiešti
}
}
Pavyzdys naudojant setNeedsLayout():
class MyContainerView: UIView {
private let subview: UIView
init(subview: UIView) {
self.subview = subview
super.init(frame: .zero)
addSubview(subview)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) neįgyvendinta")
}
override func layoutSubviews() {
super.layoutSubviews()
// Subview rėmo atnaujinimas
subview.frame = bounds.insetBy(dx: 10, dy: 10)
}
func rearrangeSubviews() {
// Subview išdėstymo keitimas
setNeedsLayout() // Planavimas išdėstymo atnaujinimui
}
}