Published on

Keshlash va ishlash ko'rsatkichlari

Authors

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)")
        }
    }
}
QatorVazifasi
URLCache(memoryCapacity:diskCapacity:diskPath:)Xotira va disk limitlari bilan maxsus kesh yaratadi. Ilovangizning tarmoq talablariga moslangan.
sorov.cachePolicy = .returnCacheDataElseLoadAvval 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 = 100NSCache 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

StrategiyaVazifasi
.useProtocolCachePolicyStandart — serverning kesh ko'rsatmalarini kuzatadi
.returnCacheDataElseLoadAvval kesh, tarmoq faqat kerak bo'lganda
.reloadIgnoringLocalCacheDataHar doim yangi yuklash — ma'lumot real vaqtda o'zgarsa
.returnCacheDataDontLoadFaqat 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

VositaVazifasi
URLCacheHTTP javoblarini saqlaydigan tizim HTTP keshi
NSCacheXotira bosimi ostida avtomatik tozalanadigan xotira keshi
.returnCacheDataElseLoadAvval kesh, yo'q bo'lsa tarmoq — eng keng tarqalgan strategiya
@MainActorKlassni asosiy oqimga bog'laydi — thread-safe UI yangilanishi
PaginationKichik 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.

Buy mea coffee