Sobes.tech
Middle

Zašto se ne preporučuje opterećivanje glavne niti u iOS-u i koje su metode za to izbegavanje?

sobes.tech АИ

Одговор од АИ

Главна нит је одговоран за ажурирање корисничког интерфејса и обраду догађаја UI-а. Све дуготрајне операције (мрежни захтеви, тешки рачунски задаци, рад са датотекама) на главној нитки ће га блокирати, што ће довести до "замрзнутог" UI-а, ниске одзивности апликације и чак њеног пада (watchdog timeout).

Начини за избегавање оптерећења главне нитке:

  1. Grand Central Dispatch (GCD): Омогућава извршавање задатака асинхроно у позадинским редовима.

    • DispatchQueue.global(): Добијање глобалних позадинских редова са различитим приоритетима.
    • DispatchQueue.main: Главни ред за ажурирање UI-а.
    • async { ... }: Асинхроно извршавање блока кода.
    // извршавање тешког задатка у позадинском току
    DispatchQueue.global(qos: .userInitiated).async {
        // тешки рачунски задаци или мрежни захтев
    
        // ажурирање UI-а на главном току
        DispatchQueue.main.async {
            // ажурирање корисничког интерфејса
        }
    }
    
  2. Operation Queues (Operation & OperationQueue): Виши ниво апстракције над GCD редовима, подржава зависности између операција, отказивање и паузирање.

    • OperationQueue(): Креирање реда операција.
    • Operation: Аборстрактна класа за задатке који се могу додати у ред.
    • addOperation(_:): Додавање операције у ред.
    let downloadOperation = BlockOperation {
        // преузимање података
    }
    
    let parseOperation = BlockOperation {
        // обрада података
    }
    
    // зависност: обрада почиње након преузимања
    parseOperation.addDependency(downloadOperation)
    
    let queue = OperationQueue()
    queue.addOperation(downloadOperation)
    queue.addOperation(parseOperation)
    
  3. Concurrency (async/await): Модеран приступ у Swift-у за асинхроно програмирање.

    • async: Обележава функцију као асинхрону.
    • await: Чека на завршетак асинхроне операције.
    • Task: Креирање нове конкурентне задатке.
    func fetchData() async throws -> Data {
        let url = URL(string: "https://example.com/data")!
        let (data, _) = try await URLSession.shared.data(from: url)
        return data
    }
    
    func updateUI() {
        Task {
            do {
                let data = try await fetchData()
                // обрада података
                // аутоматско ажурирање UI-а на главном току
                // (ако се Task креира у главном Actor-у или DispatchQueue.main)
            } catch {
                // обрада грешке
            }
        }
    }
    
  4. Actors: Превентивно спречавају трке података приликом приступа из различитих конкурентних контекста, обезбеђујући ексклузиван приступ својем стању.

    actor DataStore {
        private var data: [String] = []
    
        func addData(_ item: String) {
            data.append(item)
        }
    
        func getData() -> [String] {
            return data
        }
    }
    
    let store = DataStore()
    
    Task {
        await store.addData("item1")
    }
    

Избор између GCD, Operation Queues и Concurrency зависи од сложености задатка, потребног нивоа контроле и захтева за структуром кода. Concurrency је пожељан приступ у савременим апликацијама због читљивости и безбедности.