- Published on
Keshlash va ishlash ko'rsatkichlari
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Tarmoq samaradorligi faqat "tezkor" bo'lishni anglatmaydi — bir xil ma'lumotni qayta-qayta so'ramаslik, katta yuklamalarsiz UI ni silliq saqlash va xotira tejash haqida. Ushbu darsda amalda zarur bo'lgan keshlash vositalari ko'rib chiqiladi.
URLCache — HTTP keshlash
URLCache HTTP javoblarini saqlaydigan tizim komponenti. Keshi bor so'rov uchun URLSession tarmoq so'rovi qilish o'rniga keshdan qaytarishi mumkin.
// URLCache sozlash (AppDelegate yoki app boshlanishida)
let keshlash = URLCache(
memoryCapacity: 50_000_000, // 50 MB xotira
diskCapacity: 200_000_000, // 200 MB disk
diskPath: "api_keshi"
)
URLCache.shared = keshlash
// Kesh siyosatli so'rov
var sorov = URLRequest(url: url)
sorov.cachePolicy = .returnCacheDataElseLoad // Avval kesh, yo'q bo'lsa tarmoq
// sorov.cachePolicy = .reloadIgnoringLocalCacheData // Har doim yangi yuklash
// sorov.cachePolicy = .returnCacheDataDontLoad // Faqat kesh, tarmoqsiz
let (data, _) = try await URLSession.shared.data(for: sorov)
import SwiftUI
struct Post: Codable, Identifiable {
let id: Int
let title: String
let body: String
}
// NSCache rasm keshlash uchun — tizim xotirasi kamaysa avtomatik tozalanadi
final class RasmKeshi: ObservableObject {
static let shared = RasmKeshi()
private let kesh = NSCache<NSURL, UIImage>()
private init() {
kesh.countLimit = 100 // Maksimal 100 ta rasm
kesh.totalCostLimit = 50_000_000 // 50 MB limit
}
func rasm(url: URL) -> UIImage? {
return kesh.object(forKey: url as NSURL)
}
func saqlа(rasm: UIImage, url: URL) {
kesh.setObject(rasm, forKey: url as NSURL)
}
}
// URLCache bilan kesh siyosatli so'rov misoli
struct KeshlanganPostlar: View {
@State private var posts: [Post] = []
@State private var yuklanmoqda = true
@State private var keshDan = false
var body: some View {
VStack {
if keshDan {
Label("Keshdan yuklandi", systemImage: "bolt.fill")
.font(.caption)
.foregroundStyle(.green)
.padding(.horizontal)
}
if yuklanmoqda {
ProgressView("Yuklanmoqda...")
} else {
List(posts) { post in
VStack(alignment: .leading) {
Text(post.title).font(.headline)
Text(post.body)
.font(.caption)
.foregroundStyle(.secondary)
.lineLimit(2)
}
}
}
}
.task {
await postlarniOlKesh()
}
}
func postlarniOlKesh() async {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
// Kesh siyosatli URLRequest
var sorov = URLRequest(url: url)
sorov.cachePolicy = .returnCacheDataElseLoad
do {
let (data, javob) = try await URLSession.shared.data(for: sorov)
// HTTP javobidan kesh ishlatilganligini tekshirish
if let httpJavob = javob as? HTTPURLResponse {
// Status 304 = o'zgarmagan (kesh ishlatildi)
await MainActor.run {
keshDan = httpJavob.statusCode == 304
}
}
let decoded = try JSONDecoder().decode([Post].self, from: data)
await MainActor.run {
posts = decoded
yuklanmoqda = false
}
} catch {
print("Xato: \(error)")
}
}
}
| Qator | Vazifasi |
|---|---|
URLCache(memoryCapacity:diskCapacity:diskPath:) | Xotira va disk limitlari bilan maxsus kesh yaratadi. Ilovangizning tarmoq talablariga moslangan. |
sorov.cachePolicy = .returnCacheDataElseLoad | Avval keshni tekshiradi. Topilsa keshdan qaytaradi. Topilmasa tarmoq so'rovi qiladi. Tarmoq talabini kamaytirish uchun eng keng tarqalgan strategiya. |
NSCache<NSURL, UIImage>() | Rasm keshi uchun. Tizim xotirasi kamaysa avtomatik tozalanadi. Dictionary dan farqli o'laroq xotirani o'zi boshqaradi. |
kesh.countLimit = 100 | NSCache saqlaydigan ob'ektlar sonini cheklaydi. Bu sondan oshsa, eski yozuvlar olib tashlanadi. |
Umumiy ishlash ko'rsatkichlari muammolari
// ❌ Yomon — fon oqimidan UI yangilash
func yukla() async {
let data = try await URLSession.shared.data(from: url)
posts = try JSONDecoder().decode([Post].self, from: data) // XAVFLI!
}
// ✅ Yaxshi — asosiy oqimda UI yangilash
func yukla() async {
let data = try await URLSession.shared.data(from: url)
let decoded = try JSONDecoder().decode([Post].self, from: data)
await MainActor.run { posts = decoded }
}
// @MainActor bilan butun klass asosiy oqimda — oddiy yechim
@MainActor
class PostlarViewModel: ObservableObject {
@Published var posts: [Post] = []
func yukla() async {
// Barcha xususiyat yangilanishlari avtomatik asosiy oqimda
}
}
Kesh strategiyalari
| Strategiya | Vazifasi |
|---|---|
.useProtocolCachePolicy | Standart — serverning kesh ko'rsatmalarini kuzatadi |
.returnCacheDataElseLoad | Avval kesh, tarmoq faqat kerak bo'lganda |
.reloadIgnoringLocalCacheData | Har doim yangi yuklash — ma'lumot real vaqtda o'zgarsa |
.returnCacheDataDontLoad | Faqat kesh — oflayn rejim uchun |
Sahifalash (pagination)
// Barcha yozuvlarni bir vaqtda emas, sahifalab yuklash
struct SahifalanganKo'rinish: View {
@State private var posts: [Post] = []
@State private var joriySahifa = 1
var body: some View {
List(posts) { post in
PostQatori(post: post)
.task {
// Oxirgi elementga yetilganda keyingi sahifani yuklash
if post.id == posts.last?.id {
await keyingiSahifaniYukla()
}
}
}
.task { await birinchiSahifaniYukla() }
}
func birinchiSahifaniYukla() async { /* ... */ }
func keyingiSahifaniYukla() async { /* ... */ }
}
Tezkor ma'lumotnoma
| Vosita | Vazifasi |
|---|---|
URLCache | HTTP javoblarini saqlaydigan tizim HTTP keshi |
NSCache | Xotira bosimi ostida avtomatik tozalanadigan xotira keshi |
.returnCacheDataElseLoad | Avval kesh, yo'q bo'lsa tarmoq — eng keng tarqalgan strategiya |
@MainActor | Klassni asosiy oqimga bog'laydi — thread-safe UI yangilanishi |
Pagination | Kichik bo'laklarda yuklash — xotira va tarmoq samaradorligi |
🎯 Topshiriq: kesh nazorati
8.2 darsdan PostListView ni kesh siyosati bilan yangilang. returnCacheDataElseLoad ishlating. "Yangilash" tugmasi qo'shing — bosishda .reloadIgnoringLocalCacheData bilan yangi so'rov qilsin. Foydalanuvchi qachon yangi ma'lumot va qachon keshdan ma'lumot ko'rayotganini Text bilan ko'rsating.