未使用的不可变接收器的编译器警告,但使用 _ 导致测试失败
Compiler warning for unused immutable sink, but using _ causes test to fail
我有一个测试可以验证在新设备可用时是否正在发布消息:
let deviceConnectedPublisher = NotificationCenter.default.publisher(for: .deviceAdded)
.compactMap { [=10=].object as AnyObject as? ConnectableDevice }
let sink = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
这工作得很好,但我有一个编译器警告:
Initialization of immutable value 'sink' was never used; consider replacing with assignment to '_' or removing it
但是如果我接受编译器的建议并将其更改为
let _ = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
然后我的测试超时,随后失败。有没有更好的方法来申报我的水槽?有什么方法可以告诉编译器这是错误的吗?这应该作为错误提交吗?我理解为什么编译器认为该变量未被使用,但在这种情况下似乎应该有一种方法来禁用警告——或者更有可能——我正在做一些不符合预期的事情。
编译器向您提示的是接收器需要存储。通常的做法是写
deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}.store(in: &self.storage)
...其中 storage
是 Set<AnyCancellable>
或 [AnyCancellable]
实例 属性。这使管道保持活动状态并赋予其自动绑定到周围对象(例如视图控制器)的生命周期。
在您将 AnyCancellable
存储在名为 sink
的本地 属性 中的代码中,编译器会发出您从未使用过该变量的警告。这意味着允许编译器优化变量并立即销毁 AnyCancellable
。
但是,您可能 运行 在调试构建配置中进行测试。调试配置的默认设置禁用优化。因此,编译器 不会 优化掉 sink
变量,并且只会在作用域结束时销毁它。到那时,我想您已经发布了您期望的通知。
在您使用 _
的代码中,编译器会立即销毁返回的 AnyCancellable
。这会取消您对通知发布者的订阅,因此通知永远不会发送到您的 sink
闭包。
您可以使警告静音,并确保本地 属性 的值直到稍后才被破坏,使用 withExtendedLifetime
函数:
let sink = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
// post notification here
withExtendedLifetime(sink) { }
// Only now can sink be destroyed.
我有一个测试可以验证在新设备可用时是否正在发布消息:
let deviceConnectedPublisher = NotificationCenter.default.publisher(for: .deviceAdded)
.compactMap { [=10=].object as AnyObject as? ConnectableDevice }
let sink = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
这工作得很好,但我有一个编译器警告:
Initialization of immutable value 'sink' was never used; consider replacing with assignment to '_' or removing it
但是如果我接受编译器的建议并将其更改为
let _ = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
然后我的测试超时,随后失败。有没有更好的方法来申报我的水槽?有什么方法可以告诉编译器这是错误的吗?这应该作为错误提交吗?我理解为什么编译器认为该变量未被使用,但在这种情况下似乎应该有一种方法来禁用警告——或者更有可能——我正在做一些不符合预期的事情。
编译器向您提示的是接收器需要存储。通常的做法是写
deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}.store(in: &self.storage)
...其中 storage
是 Set<AnyCancellable>
或 [AnyCancellable]
实例 属性。这使管道保持活动状态并赋予其自动绑定到周围对象(例如视图控制器)的生命周期。
在您将 AnyCancellable
存储在名为 sink
的本地 属性 中的代码中,编译器会发出您从未使用过该变量的警告。这意味着允许编译器优化变量并立即销毁 AnyCancellable
。
但是,您可能 运行 在调试构建配置中进行测试。调试配置的默认设置禁用优化。因此,编译器 不会 优化掉 sink
变量,并且只会在作用域结束时销毁它。到那时,我想您已经发布了您期望的通知。
在您使用 _
的代码中,编译器会立即销毁返回的 AnyCancellable
。这会取消您对通知发布者的订阅,因此通知永远不会发送到您的 sink
闭包。
您可以使警告静音,并确保本地 属性 的值直到稍后才被破坏,使用 withExtendedLifetime
函数:
let sink = deviceConnectedPublisher.sink { _ in
expectation.fulfill()
}
// post notification here
withExtendedLifetime(sink) { }
// Only now can sink be destroyed.