Странное поведение в swiftUI + Combine когда класс -> структура - PullRequest
0 голосов
/ 04 апреля 2020

В видео-уроке на YouTube одна вещь привлекла мое внимание. Я создал действительно простой проект, чтобы воспроизвести его. Я знаю, что дизайн кода не идеален, но мне интересно, почему код ведет себя так в данной конкретной ситуации.

file # 1

import SwiftUI

struct ContentView: View {

    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        Text(viewModel.content).onAppear() {
            self.viewModel.subsribe()
        }
    }
}

file # 2

import Combine

class ViewModel: ObservableObject {

    private let model = Model()
    @Published var content: String = ""
    var subscription: AnyCancellable?

    func subsribe() {
        subscription = model.getPublisher().sink { value in
            self.content = value
        }
    }
}

file # 3

import Foundation
import Combine

class Model {

    func getPublisher() -> AnyPublisher<String, Never> {
        Just("Test")
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }
}

В этом коде все работает как положено. Но если в файле # 3 class Model изменить на struct Model, он перестанет работать!
Это очень странно, потому что ... кажется, не имеет никакого значения.

Подсказка # 1
В Факт, что мы все еще получаем сообщение от издателя. Но представление не обновляет его.

Подсказка # 2
Если мы слегка изменим код в файле # 2

private let publisher = Model().getPublisher()

func subsribe() {
    subscription = publisher.sink { value in
        self.content = value
    }
}

Это работает в обоих случаях (с class и с struct)

Подсказка № 3 (отредактировано из-за комментария @Sweeper)
В файле № 2, если мы возьмем строку кода private let model = Model() и переместим ее в нижнюю часть следующим образом:

    class ViewModel: ObservableObject {

        @Published var content: String = ""
        var subscription: AnyCancellable?
        private let model = Model()

        func subsribe() {
            subscription = model.getPublisher().sink { value in
                self.content = value
            }
        }
    }

Код начинает работать !!!
Кто-нибудь еще может воспроизвести это поведение?

PS
Ссылка на оригинальный видеоурок: Видео

...