- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的主要问题是我正在尝试解决(未记录的)事实,即 @Published
属性在订阅者收到更改通知之前不会更新属性的值。我似乎找不到解决它的好方法。
考虑以下 Subject
和 @Published
属性的人为组合。首先,一个简单的类:
class StringPager {
@Published var page = 1
@Published var string = ""
}
let pager = StringPager()
然后是一个简单的直通主题:
let stringSubject = PassthroughSubject<String, Never>()
为了调试,让我们订阅字符串属性并打印出来:
pager.$string.sink { print($0) }
到目前为止一切顺利。接下来,让我们订阅主题并根据其值更改寻呼机:
stringSubject.sink { string in
if pager.page == 1 {
pager.string = string
} else {
pager.string = string.uppercased()
}
}
希望这个逻辑能让我们在不在第一页时将寻呼机字符串设为大写。
现在让我们在页面更新时通过 stringSubject 发送值:
pager.$page.sink {
$0 == 1 ? stringSubject.send("lowercase") : stringSubject.send("uppercase")
}
如果我们的逻辑正确,那么小写字母将始终小写,而大写字母将始终大写。不幸的是,事实并非如此。这是一个示例输出:
pager.page = 1 // lowercase
pager.page = 2 // uppercase
pager.page = 3 // UPPERCASE
pager.page = 4 // UPPERCASE
pager.page = 1 // LOWERCASE
pager.page = 1 // lowercase
原因是当我们订阅主题时,我们检查 pager.page
的值...但是更新 pager.page
是触发主题的闭包,因此 pager.page
还没有更新值,因此主体执行了错误的分支。
我已经尝试通过在下沉之前将 pager.$page
与主题一起zip
来解决这个问题:
stringSubject.zip(pager.$page).eraseToAnyPublisher().sink { ...same code... }
以及combineLatest
它:
stringSubject.combineLatest(pager.$page).eraseToAnyPublisher().sink { ...same code... }
但这会导致完全相同的观察到的行为(在前一种情况下)或同样不受欢迎的行为,除了更多(在后一种情况下)。
如何获取主题 sink
闭包中的当前页面?
最佳答案
问题是您实际上并没有使用 Combine 框架的强大功能。您不应该使用 sink
闭包来查看任何值。这颠覆了Combine的全部意义!相反,您应该让该值流入您的接收器
,作为您构建的 Combine 管道的一部分。
让我们从您的 StringPager 开始:
class StringPager {
@Published var page = 1
@Published var string = "this is a test"
}
让我们有一个包含 StringPager 的 View Controller 类,以及一些设置其字符串或页码的测试按钮:
class ViewController: UIViewController {
let pager = StringPager()
var storage = Set<AnyCancellable>()
override func viewDidLoad() {
// ...
}
@IBAction func doButton(_ sender: Any) {
let i = Int.random(in: 1...4)
print("setting page to \(i)")
self.pager.page = i
}
@IBAction func doButton2(_ sender: Any) {
let s = ["Manny", "Moe", "Jack"].randomElement()!
print("setting string to \(s)")
self.pager.string = s
}
}
你看这个试验台的想法是什么。我们单击第一个按钮或第二个按钮,然后将寻呼机的页面或字符串随机设置为一个新值,并在控制台中报告它是什么。
我们现在的目标是创建一个 Combine 管道,它会在每次字符串或页面更改时吐出寻呼机字符串的大写或非大写版本,具体取决于寻呼机的页面是否为 1。我将在 viewDidLoad
中执行此操作。 Combine 运算符监视任何多个发布者的变化并在其中任何一个发生变化时报告它们的当前值是 combineLatest
,所以这就是我将使用的:
pager.$page.combineLatest(pager.$string)
.map {p,s in p > 1 ? s.uppercased() : s}
.sink {print($0)}.store(in:&storage)
就是这样!现在我将点击按钮几次,让我们看看我们得到了什么:
this is a test
setting page to 3
THIS IS A TEST
setting page to 3
THIS IS A TEST
setting page to 1
this is a test
setting string to Jack
Jack
setting string to Manny
Manny
setting page to 1
Manny
setting page to 1
Manny
setting page to 4
MANNY
setting string to Manny
MANNY
setting string to Moe
MOE
setting string to Jack
JACK
如您所见,每次我们更改页面或字符串时,我们都会从管道末端获得一个新值,而且它是正确的值!如果页面大于 1,我们得到字符串的大写版本;如果页面为 1,我们将按原样获取字符串。任务完成!
关于ios - 从其他地方合并 @Published 属性 : get current value during update,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59242482/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
操作无法完成。 Places API 库中发生内部错误。如果您认为此错误代表错误,请使用我们社区和支持页面 (https://developers.google.com/places/support)
我正在尝试在我的项目中使用 google places,我将其设置在 fragment 中而不是 Activity 中,我的自动完成 fragment 在 fragment 中。但是,当我尝试搜索它时
我的目的是使用R来查询google api。 我有一个地址和名称列表(属于商店、餐馆等),我需要为每个地址和名称存储: “纬度”、“经度”、“业务类型” 我的想法是使用 google place ap
我正在寻找设置一个自动完成的谷歌地方小部件。 我有一个带有“searchFieldText”id 的输入类型文本。 这是我的 JS 代码: var inputsec = document.getEle
是否可以使用图形 API(或地址/ zip )按纬度/经度和半径获取地点?我在文档中的任何地方都看不到它 最佳答案 搜索 URL 的以下格式将返回某个位置附近的地点列表: https://graph.
我正在探索 Google API,主要是 Places API。由于对 Google Places API 的请求数限制为 100,000,因此我正在寻找方法来最大限度地减少发送到 API 的请求数。
伙计们,我在我的应用程序中有一个功能,可以使用 GetFiles 在特定目录中搜索特定文件。方法 System.IO.Directory.GetFiles(string path, string
我已经在 Laravel 5.3 上使用 where 查询成功创建了许多函数,但是这次发生了一些奇怪的事情。 public function show($id){ $artikel = Art
我正在为我的 iPhone 应用程序使用 Facebook 图形 API 来获取附近地点的列表,我使用带有一些参数的“搜索”请求。我得到的响应是一个包含以下信息的地点列表:“纬度”、“经度”、“名称”
我有一个 Android 应用程序,我在其中使用 Google map 显示附近的地方,如加油站、药店等。我正在使用 map 和地点 API。 https://maps.googleapis.com/
我是一名优秀的程序员,十分优秀!