Xcode 11 beta 5在调用@Published变量的sink方法时出现Abort trap: 6错误

3

我在一个仓库类中使用了 @Published变量来表示我的用户状态。

@Published public var state: UserState = .initial

在测试中,我使用sink来轻松观察更改,并满足测试的期望。

原始测试代码如下:

sub = Authentication.shared.$state.receive(on: DispatchQueue.main).sink(receiveValue: { state in
    expectation.fulfill()
})
Authentication.shared.login(with: Credentials(email: "gujci@gmail.com", password: "asdasd"))

这将导致编译器错误,例如以下代码Abort trap: 6

Global is external, but doesn't have external or weak linkage!
i64* @"$s14TestRepository14AuthenticationC6_state33_B23F0E9C543FDF10733C02EF2F1E18CCLL7Combine9PublishedVyAA9UserStateOGvpWvd"
<unknown>:0: error: fatal error encountered during compilation; please file a bug report with your project and the crash log
<unknown>:0: note: Broken module found, compilation aborted!
Stack dump:
...

这种情况发生在一个与应用程序不同的Swift包中的项目。
当我尝试从应用程序(而非测试)中使用它时,结果相同。此外,我尝试了其他发布者例如JustFuture从网络调用返回,所有这些都可以正常使用sink
我从beta 4开始遇到了这个问题,但以前没有尝试过,在之前的版本中可能也存在这个问题。我注意到在beta 4和5之间Combine做了很大的改变,但是这个错误仍然存在。
有没有人成功地使用@Published库中的sink函数而没有出现这样的错误?
如果我误解了什么,请纠正我,目前我必须假设问题出在Apple那里。
1个回答

3

最终,我通过直接定义一个publisher,省略了@Published关键字来解决这个问题。

public private(set) var state: CurrentValueSubject<UserState, Never> = .init(.initial)

可以类似地使用。

这让我想到,@Published 只适用于与 SwiftUI 进行交互,在更深的层次上,我应该使用来自 Combine 的显式发布者。你对此有何想法?


请问您能否解释一下如何使用这个发布者(Publisher),而不是使用 @Published?我遇到了同样的情况,试图将我的 ObservableObject 的实现分成超类和子类,尝试将我的 @Published 变量更改为 CurrentValueSubject,但是当我更改这些变量的值时,SwiftUI 不会重新渲染。我尝试过使用 send(),也尝试过每次重新初始化它们。我需要在 SwiftUI 视图中订阅这些变量吗? - Randex
1
如果您在ViewModel中有一个非@Published属性,则必须手动调用objectWillChange.send()来通知SwiftUI视图。由于可以轻松订阅CurrentValueSubject,因此可以在sink中调用它。只是不要忘记使用主运行循环并存储订阅。(我通常使用private var subscriptions: Set<AnyCancellable> = []来实现这个目的) - gujci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接