- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
I know there have been I would say similar questions, but none of them fits my case -> see my already tried attempts below.
所以我想做的是制作一个高级搜索栏。因此,每次 searchParam 更改时,我都需要执行代码来检查我的 TableViewItems(数组)是否符合条件 -> 过滤器。
当 smo.例如输入 3 个字符,我的代码检查这个字符串。但这需要一段时间才能获得所有结果。
问题:当 smo。然后键入第 4 个字符,我想停止之前的执行并开始一个新的字符串 4。
我的尝试:
使用 DispatchWorkItem:
这里的问题是它只改变了一个 bool 值,代码需要 10 秒以上的时间才能识别它改变了。如果我执行 .sync
而不是 .async
就可以工作,但它会使应用卡住超过 10 秒
使用 DispatchQueue:
无法停止,只能暂停 -> 所以会保留在内存中 -> 会垃圾内存
在每个 for 循环
中检查 bool 值:
与 DispatchWorkItem 相同,需要 10 秒以上才能识别更改
当前代码:(不是很重要)
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.stop = true
if people != nil {
if searchText.isEmpty {
searchedPeople = people
self.stop = false
} else {
self.searchedPeople = []
self.tableView.reloadData()
workItem = DispatchWorkItem(qos: .userInitiated, flags: []) {
outter: for i in 0...searchText.count - 1 {
if self.stop { self.stop = false;break outter } //
if i == 0 {
inner: for person in self.people! {
if self.stop { self.stop = false;break outter } //
let name = (person.Vorname != nil ? person.Vorname! + " " : "") + (person.Nachname ?? "")
if name.lowercased().contains(searchText.lowercased()) {
print("Found: \(name), \(searchText), Exact Match")
self.searchedPeople?.append(person);DispatchQueue.main.async { self.tableView.reloadData()}; continue inner
}
}
} else {
let firstP = searchText.prefix(i+1)
let lastP = searchText.suffix(searchText.count - i + 1)
inner2: for person in self.people! {
if self.stop { self.stop = false;break outter } //
let name = (person.Vorname != nil ? person.Vorname! + " " : "") + (person.Nachname ?? "")
if name.lowercased().contains(firstP.lowercased()) && (name.lowercased().contains(lastP.lowercased())) {
print("Found: \(name), \(searchText), First: \(firstP), Last: \(lastP)")
self.searchedPeople?.append(person)
DispatchQueue.main.async { self.tableView.reloadData()}
continue inner2
}
}
}
}
}
//execute
DispatchQueue.async(execute: workItem)
}
}
}
最佳答案
从本质上讲,您的问题是,当您应该检查本地状态时,您却在检查全局状态。假设您正在进行操作“L”,并且您刚刚键入了“e”,因此操作“Le”将开始。这是大致发生的事情:
func updateMyPeepz() {
// At this point, `self.workItem` contains operation 'L'
self.workItem.cancel() // just set isCancelled to true on operation 'L'
self.workItem = DispatchWorkItem { /* bla bla bla */ }
// *now* self.workItem points to operation 'Le'!
}
稍后,在操作“L”的工作项中,您执行以下操作:
if self.workItem.isCancelled { /* do something */ }
不幸的是,此代码在操作“L”中运行,但 self.workItem
现在指向操作“Le”!因此,当操作“L”被取消而操作“Le”没有被取消时,操作“L”会看到 self.workItem
——即操作“Le”——没有被取消。因此,检查始终返回 false
,并且操作“L”实际上从未停止。
当您使用全局 bool 变量时,您会遇到同样的问题,因为它是全局的,并且不会区分应该仍在运行的操作和不应该运行的操作(除了原子性问题之外,您已经如果您不使用信号量保护变量,将要介绍)。
修复方法如下:
func updateMyPeepz() {
var workItem: DispatchWorkItem? = nil // This is a local variable
self.currentWorkItem?.cancel() // Cancel the one that was already running
workItem = DispatchWorkItem { /* bla */ } // Set the *local variable* not the property
self.currentWorkItem = workItem // now we set the property
DispatchQueue.global(qos: whatever).async(execute: workItem) // run it
}
现在,这是关键部分。在你的循环中,像这样检查:
if workItem?.isCancelled ?? false // check local workItem, *not* self.workItem!
// (you can also do workItem!.isCancelled if you want, since we can be sure this is non-nil)
在 workItem 的末尾,将 workItem 设置为 nil
以摆脱保留周期(否则会泄漏):
workItem = nil // not self.workItem! Nil out *our* item, not the property
或者,您可以将 [weak workItem] in
放在 workItem
block 的顶部以防止循环——这样您就不必在结束了,不过你一定要用?? false
而不是 !
因为你总是想假设一个弱变量可以随时变为 nil。
关于ios - swift |强制取消执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51506072/
是否可以使用标准输入/标准输出在 bash 中压缩/解压缩字符串? 我试过了,但显然不支持它? hey=$(echo "hello world" | gzip -cf) echo $hey # ret
我的任务是让一个企业网站适用于 IE7,它必须“足够好”,因此我禁用了任何导致问题的花哨/非必要功能。 其中之一是正在使用的搜索栏,需要进行哪些搜索,我猜测幕后某个地方有某种 JavaScript 用
我有一个执行大量处理的小程序。您可以通过按回车键打印进度。 我实现它的方法是在主线程中完成处理,同时我有一个 pthread 不断循环 getchar() 以等待输入键。 问题是当我完成处理时。发生这
我完全理解 suspendCoroutine 与 suspendCancellableCoroutine 在我的示例中的工作方式。但我想知道为什么 println("I finished") (第 1
我是 QT 的新手。目前在我的项目中我实现了 QFileDialog . 在我的用例中:每当用户选择一个文本文件时,它都会执行 functionA .但是,我发现如果在文件对话框中单击取消,funct
我有代码,仅在用户选择“另存为”时运行。为此并获取我正在使用的文件的新名称 Application.GetSaveAsFilename功能。 我遇到的问题是类型不匹配,同时检查用户是否在他没有这样做时
我的 UILocalNotification 有问题。 我正在用我的方法安排通知。 - (void) sendNewNoteLocalReminder:(NSDate *)date alrt:(NS
祝你有美好的一天 我有一个网站,其中有很多“工具提示”。这些工具提示是在将鼠标悬停在文本的特定部分上时创建的。工具提示是一个 div block ,它显示在网站上所有其他内容的顶部,并且当光标从文本移
我遇到以下问题。每隔 2 秒,程序就会进入 if 语句。在这个 if 语句中,我想要一个计时器,它会在 15 秒后给我一条消息。计时器应延迟 1 秒运行。但是当我用计时器“等待”时,if 语句将再执行
基本上我有以下代码片段, (let [task (FutureTask. fn) thr (Thread. task)] (.start thr) ;;wait for signa
取消正在进行的 ASIHttpRequest 请求的正确位置在哪里?这就是我取消的方式,但是当我 时它继续崩溃在不让请求完成的情况下从一个 View Controller 转移到另一个 View Co
我在我的 winforms 应用程序中使用 BackgroundWorker 来执行另一个类中发生的长时间运行的任务(执行数据库操作)。由于所有工作都是在另一个类中完成的,因此取消并不那么简单。我在另
我正在使用 OneSignal 向我的用户显示通知。通知工作正常,但我注意到,如果我在通知栏中“滑动”取消通知,则通知将永远保留,这是一张显示应用程序图标上的通知的图像,我想在应用程序已打开: 我看到
正在运行的 AsyncTask 的 .cancel(boolean) 方法如何工作?这是文档: Attempts to cancel execution of this task. This atte
我注意到,当我激活约束时,我会立即在该行代码处收到一条警告,指出不能同时满足约束。 我假设布局是在“UI 更新周期”之类的稍后时间点计算的,而不是每次约束都被(取消)激活。因此,在(取消)激活约束的代
这是我创建线程的方式: readFromWebThread = [[NSThread alloc] initWithTarget:self selector:@selector(loadThread:
我目前正在尝试取消与我的数据模型中的对象关联的特定 UILocalNotifications。为此,每个数据对象都有一个唯一标识符,即 NSUUID。 创建 UILocalNotification:
当我提交并单击“确定”时,它会继续,但当我按“取消”时,它仍然会提交。我尝试使用此代码,但提交和取消按钮仍然执行相同的操作。 model.saveForm = function() { var
我有一个警报弹出窗口,当发生特定操作时会出现该弹出窗口。 5 秒后,使用 setTimeout() 隐藏警报弹出窗口。 我遇到的问题是,如果我多次触发弹出窗口,有时后续的弹出窗口会出现但立即消失。我相
我有一些 javascipt (jQuery),其中单击按钮时会淡入 #myDiv,然后使用超时函数在 5 秒后再次淡出。它工作正常,但如果用户在超时内的 fadeOut 函数运行之前再次单击该按钮,
我是一名优秀的程序员,十分优秀!