Что такое GCD (Grand Central Dispatch) и как он используется при разработке под iOS в Flutter?

«Что такое GCD (Grand Central Dispatch) и как он используется при разработке под iOS в Flutter?» — вопрос из категории Платформенное взаимодействие, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

GCD (Grand Central Dispatch) — это низкоуровневый фреймворк от Apple для управления параллельными и асинхронными задачами в iOS/macOS приложениях. Он работает с очередями (queues) и потоками (threads), автоматически управляя пулом потоков.

В контексте Flutter GCD используется в нативном iOS-коде, который взаимодействует с Flutter-частью через Platform Channels (MethodChannel, EventChannel). Это необходимо для выполнения ресурсоёмких операций (обработка изображений, сложные вычисления, работа с нативными API), чтобы не блокировать главный UI-поток Flutter.

Типичный сценарий использования GCD в Flutter-плагине:

  1. Swift-код (нативная сторона плагина):
    
    import Flutter
    import Foundation

public class SwiftHeavyTaskPlugin: NSObject, FlutterPlugin { public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "heavy_task", binaryMessenger: registrar.messenger()) let instance = SwiftHeavyTaskPlugin() registrar.addMethodCallDelegate(instance, channel: channel) }

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { if call.method == "computeHash" { guard let args = call.arguments as? [String: Any], let input = args["data"] as? String else { result(FlutterError(code: "INVALID_ARGS", message: nil, details: nil)) return }

  // Отправляем тяжелую задачу в фоновую очередь GCD
  DispatchQueue.global(qos: .userInitiated).async {
      // Имитация тяжелой операции (например, хеширование)
      let computedHash = self.slowHashFunction(input)

      // Возвращаем результат в главную очередь (Main Thread), 
      // так как FlutterResult должен вызываться на главном потоке
      DispatchQueue.main.async {
          result(computedHash)
      }
  }
}

}

private func slowHashFunction(_ input: String) -> String { // ... тяжелые вычисления ... return "hashof(input)" } }


2. **Dart-код (сторона Flutter):**
```dart
import 'package:flutter/services.dart';

class HeavyTaskService {
  static const MethodChannel _channel = MethodChannel('heavy_task');

  static Future<String> computeHash(String data) async {
    try {
      final result = await _channel.invokeMethod<String>('computeHash', {'data': data});
      return result!;
    } on PlatformException catch (e) {
      print('Failed: ${e.message}');
      rethrow;
    }
  }
}

// Использование в UI
Future<void> performTask() async {
  setState(() => isLoading = true);
  final hash = await HeavyTaskService.computeHash('myData'); // Не блокирует UI
  setState(() {
    resultHash = hash;
    isLoading = false;
  });
}

Ключевые концепции GCD, релевантные для Flutter-разработчика:

  • Очереди (DispatchQueue):
    • DispatchQueue.main — главная очередь (Main Thread), используется для обновления UI.
    • DispatchQueue.global(qos:) — глобальные фоновые очереди с разными приоритетами (Quality of Service).
  • Quality of Service (QoS): Приоритеты для задач:
    • .userInteractive — для мгновенной обратной связи (анимации).
    • .userInitiated — для действий, инициированных пользователем, которые нельзя прерывать.
    • .utility — для длительных задач с индикатором прогресса.
    • .background — для задач, невидимых пользователю (синхронизация, бэкап).
  • Асинхронное выполнение: queue.async { } — не блокирует текущий поток.

Альтернатива в Dart: Для параллельных вычислений внутри Flutter-кода предпочтительнее использовать Isolates (через compute() или Isolate.spawn), так как они не разделяют память и безопасны. GCD же применяется при необходимости оптимизированной работы с нативными iOS-библиотеками или системными API.