#ios #swift #multithreading #asynchronous #combine
#iOS #быстрый #многопоточность #асинхронный #объединять
Вопрос:
У меня есть несколько шагов, которые нужно обработать синхронно. И значение, полученное в результате процесса, потребляется представлением. Он работает на iOS 14, но на iOS 13 он выходит из строя. Я использую объединение для публикации события для обновления значения, хранящегося внутри модели представления.
Это менеджер публикаций:
final class PublisherManager { static let shared = PublisherManager() private var cancellable = Setlt;AnyCancellablegt;() func mainPublisher() -gt; AnyPublisherlt;MainInput, Nevergt; { mainSubject .eraseToAnyPublisher() } let mainSubject = PassthroughSubjectlt;MainInput, Nevergt;() enum MainInput { case updateValue() } }
Это модель представления:
final class ViewModel: ObservableObject { @Published var status: Status = .checking init() { setObserver() start() } private func setObserver() { PublisherManager.shared.mainPublisher() .receive(on: RunLoop.main) .sink { [weak self] action in guard let self = self else { return } switch action { case .updateValue: self.updateValue() } }.store(in: amp;cancellable) } func start() { let dispatchGroup = DispatchGroup() let dispatchSemaphore = DispatchSemaphore(value: 1) dispatchGroup.enter() dispatchQueue.asyncAfter(deadline: DispatchTime.now() 1) { dispatchSemaphore.wait() self.getValues { //--gt; A process to call API PublisherManager.shared.pushNotificationTroubleshooterSubject.send(.updateValue()) dispatchSemaphore.signal() dispatchGroup.leave() } } dispatchGroup.notify(queue: .main) { // Notify } } private func updateValue() { status = .active } }
Когда я запускаю его, я получаю EXC_BAD_ACCESS в AppDelegate, но он вообще не выводит никаких ошибок в отладчике. Если я прокомментирую status = .active
код, он не выйдет из строя.
Что я делаю не так и как я могу решить эту проблему?
Комментарии:
1.
DispatchGroup
иDispatchSemaphore
заставить асинхронную задачу стать синхронной-ужасная практика. Особенно вCombine
контексте, который делает обработку асинхронных задач такой удобной .DispatchGroup
в любом случае, это неправильный API. Он был разработан для управления временем в группе (нескольких) асинхронных задач в цикле.2. @vadian но тогда как с этим бороться? Я имею в виду, я пытался использовать
dispatchQueue.sync
, но иначе это не работает3. Как я уже сказал, Combine предоставляет операторам возможность плавно объединять асинхронные задачи.
4. @vadian Хм, боюсь, я не совсем понял это, не могли бы вы, пожалуйста, рассказать немного подробнее?
Ответ №1:
Похоже на то, что вы сделали с DispatchGroup
и DispatchSemaphore
неправильно. Концепция объединения это похоже на асинхронное выполнение кода. Поэтому вместо того, чтобы использовать DispatchGroup
и DispatchSemaphore
просто использовать цепочку издателей с комбинациями и зависят ли действия от полученных событий
Комментарии:
1. Ответ неясен, пожалуйста, отредактируйте свой ответ, чтобы добавить некоторые детали, особенно код для описания рабочего процесса. Имейте в виду, что в вопросе указано, что он требует синхронизации задач, чтобы не перегружать вызов API чаще, чем один раз в секунду.