Выход из закрытия фиксирует мутацию себя в подписчике Swift Combine

Итак, у меня есть эта строгая функция, которая вызывает издателя Combine с целью передачи результатов другой функции. Я получаю следующую ошибку: Сообщение об ошибке

Мой фрагмент кода:

public func execute(state: FluxState?, dispatch: @escaping DispatchFunction) {
            let config = Popular(country: .usa, genres: nil)

            subscriptions = []

            let params = [
                "page": "\(self.page)",
                "per_page": "\(20)"
            ]
            print("on page \(self.page)")

            var moviesResult = [Movie]()

            SwiftRecommendations.APIService.shared
                .getMovies(settings: config, params: params)
                //.receive(on: DispatchQueue.main)
                .sink(receiveCompletion: { (completion) in
                    if case let .failure(error) = completion {
                        print("error \(error)")
                    } else {
                        self.popularMovies = moviesResult
                        dispatch(SetMovieMenuList(page: self.page,
                            list: MovieSwift.MoviesMenu.popular,
                            response: moviesResult))
                    }
                }, receiveValue: { [unowned self] in
                    moviesResult = $0
                })
                .store(in: &self.subscriptions)
        }
    }

Фрагмент SetMovieMenuList:

class SetMovieMenuList: Action {
        let page: Int
        let list: MoviesMenu
        let response: [Movie]
    }

Функция отправки — это состояние SwiftFlux, а APIService — это структура. Не уверен, что мне нужно предоставить какую-либо дополнительную информацию, но я хотел посмотреть, был ли это способ структурировать это или как мне использовать subscriptions и сохранить список фильмов в этом сценарии.

Спасибо


person Doz    schedule 10.01.2020    source источник
comment
См. stackoverflow.com/. Вы не можете использовать структуру таким образом.   -  person Rob Napier    schedule 10.01.2020
comment
Извините, не могли бы вы предоставить немного больше информации   -  person Doz    schedule 10.01.2020
comment
Связанные ответы должны содержать подробную информацию. Когда вы передаете структуру замыканию, она создает копию, поэтому self внутри замыкания не совпадает с self вне замыкания. Любая мутация, которую вы делаете внутри замыкания, не будет видна снаружи. Если вам нужно иметь несколько ссылок на один и тот же объект, вам нужен ссылочный тип (класс).   -  person Rob Napier    schedule 10.01.2020
comment
Правильно, поэтому, когда я изменяю SetMovieMenuList на класс, устанавливаю FetchMoviesMenuList и MoviesAction также на класс, ошибка исчезает, но происходит сбой в том же блоке кода из-за уже нераспределенной ссылки.   -  person Doz    schedule 10.01.2020
comment
Вероятно, это означает, что вы пытаетесь изменить объект в произвольном потоке. Объекты не потокобезопасны, если вы не сделаете что-то, чтобы сделать их таковыми. Вам нужно убедиться, что все действия происходят в одной очереди отправки. Вероятно, вы захотите добавить receive(on:) в свою цепочку, чтобы убедиться, что обработка выполняется в очереди, которую вы ожидаете.   -  person Rob Napier    schedule 10.01.2020
comment
Спасибо @RobNapier. Поэтому я попытаюсь работать с receive(on:) потоком, но что касается структуры и класса, какой подход я должен использовать, и что должно/может быть структурой, что должно/может быть классом в этом рабочем процессе   -  person Doz    schedule 10.01.2020
comment
Я не знаю, что все части здесь пытаются сделать, но ключевой момент заключается в следующем: если вас интересуют только значения свойств, то это, вероятно, значение (структура). Если вы также заботитесь об идентичности (поэтому две вещи с одинаковыми значениями свойств могут быть разными вещами), вам нужен ссылочный тип (класс). Так, например, если вы хотите что-то наблюдать, это что-то должно быть ссылкой (вы не можете наблюдать само 4, значение; вы можете наблюдать только то, что содержит 4, ссылку).   -  person Rob Napier    schedule 10.01.2020
comment
Обычно что-то вроде APIService будет классом, поскольку вам нужен только один из них (и каждый раз, когда вы передаете структуру, вы делаете независимую копию). Тот факт, что вы можете настроить его, убедительно указывает на то, что это действительно ссылочный тип, поскольку у него есть внутреннее состояние, которым вы хотите поделиться. (Но ваш API немного сбивает с толку, потому что что, если две вещи работают одновременно, и каждая устанавливает токен API для разных вещей?)   -  person Rob Napier    schedule 10.01.2020
comment
Тот факт, что вы хотите, чтобы какая-то асинхронная операция модифицировала MoviesActions.subscriptions, также настоятельно предполагает, что это должен быть класс (но это очень сбивает с толку, потому что похоже, что .subscriptions является статическим свойством, что также кажется очень неправильным).   -  person Rob Napier    schedule 10.01.2020
comment
Хорошо, спасибо... У меня был subscriptions как статический, потому что он в структуре и получил эту собственную ошибку. Но похоже, что я должен ссылаться и иметь только одну ссылку, а не значения... Спасибо!   -  person Doz    schedule 10.01.2020
comment
@RobNapier, так что у меня есть все они как классы, протестированные с помощью .receive(on: как в maintop, так и в фоновом режиме, и все равно получаю сбой. Я даже не могу сделать статический анализатор или что-то еще, чтобы приостановить, чтобы доказать, кто виноват. Это очень расстраивает.. ааа   -  person Doz    schedule 10.01.2020
comment
Я бы объединил это как новый вопрос, включая детали сбоя и, в идеале, минимальный пример, демонстрирующий проблему. (Просто создание этого примера и выяснение того, какие части необходимы для создания сбоя, часто приводит вас к решению.) Если это реальная ошибка памяти (а не сбой утверждения), то это почти всегда происходит из-за межпоточности. доступа или с использованием Unsafe типов. В противном случае Swift безопасен и не сможет неправильно обращаться к памяти. Однако чаще сбой является утверждением, и вам следует внимательно читать напечатанные сообщения.   -  person Rob Napier    schedule 10.01.2020
comment
Звучит честно, спасибо. Да, я сделаю это   -  person Doz    schedule 10.01.2020