问题标签 [ios-multithreading]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ios - 原子属性包装器仅在声明为类而不是结构时才有效
我在 Swift 中创建了一个“锁”,并为我的 Swift 类创建了一个使用该锁的 Atomic 属性包装器,因为 Swift 缺少 ObjC 的atomic
property 属性。
当我在启用线程清理器的情况下运行测试时,它总是在使用我的 Atomic 属性包装器的属性上捕获数据竞争。
唯一有效的是将属性包装器的声明更改为类而不是结构,这里的主要问题是:为什么它有效!
我print
在属性包装器中添加了 s 和 lockinit
来跟踪创建的对象的数量,它与 struct/class 相同,尝试在另一个项目中重现问题,也没有用。但我会添加与问题相似的文件,并让我知道它为什么起作用的任何猜测。
锁
原子属性包装器
模型(数据竞争应该发生在publicVariable2
此处的属性上)
更新 1: 完整的 Xcode 项目:https ://drive.google.com/file/d/1IfAsOdHKOqfuOp-pSlP75FLF32iVraru/view?usp=sharing
ios - ViewDidAppear 不从 Firebase 更新我的图片,但更新文本信息
我对 IOS 编程还是很陌生,在使用 Firebase 数据库和存储时遇到了问题。这是图像:
这是配置文件在编辑之前的样子。如果用户点击编辑按钮,我们将进入编辑模式。
在编辑过程中,我们更改了它的名称、描述、人物图标和横幅图片,当我们完成它时,它会回到这个配置文件并查看更新的文件。但是,编辑后,它返回的是这样的:
名称和描述确实改变了,但头像没有改变。事实上,如果我再次编辑配置文件,它将更新到我更改的最后一张图片。如果我退出并返回个人资料页面,它将显示正确的图片,这是最后更新的图片。这是我在配置文件视图控制器中的代码:
并且函数ViewDidAppear
是完全相同的代码(除了super.viewDidAppear(animated)
)。我觉得这与线程有关,因为我确实将下载线程与主线程异步以确保配置文件得到更新,但我对 IOS 中的线程仍然很陌生,无法判断这是否是这里的问题. 请帮忙,谢谢!
编辑用户信息的代码:
让我知道您是否还需要在DataManager
. 它是一个包含 Firebase 数据库 API 调用的辅助类。
代码viewDidAppear()
:
更新:感谢@Pratik Prajapati,问题是我在图片更新之前过早地刷新了页面,所以我已经将我的代码重新写入其中,并且它有效!
但是,我确实认为这不是正确的方法。我实际上已经将 3 个完成块链接在一起,上传实际上需要一秒钟才能从编辑切换回配置文件。我肯定做错了什么。关于如何改进此代码的任何建议?如果我有 10 个信息而不是 3 个要更新怎么办?我不能将 10 个完成块链接在一起!
无论如何,感谢提供信息的家伙。我确实学到了很多东西!
ios - iOS NSInternalInconsistencyException 线程冲突崩溃
我有一个第三方 iOS 应用程序使用的 iOS SDK 项目,最近报告了围绕 SDK 中一个 API 的崩溃,原因是:
第三方应用程序调用的 API 是异步的,它在后台线程中异步执行一些操作,并在主线程上向调用者返回一个回调。
我知道在后台线程而不是主线程中执行 UI 操作时经常会引发此异常。
但是,我不明白为什么仍然会发生这种情况,因为在该 SDK API 中,在将回调返回给调用者之前,我有以下代码来确保调用者在主线程上获得回调:
堆栈跟踪:
调用者是否仍有可能在后台线程中获得回调?
ios - 如何将 newBackgroundContext() 与 URLSession.shared.dataTaskPublisher 一起使用?
我在 Github 创建了一个简单的 Core Data 项目来演示我的问题:
我的测试应用程序下载一个 JSON 对象列表,将其存储在 Core Data 中,并通过@FetchRequest
.
因为对象列表在我的真实应用程序中有 1000 多个元素,所以我想将实体保存到后台线程而不是主线程上的核心数据中。
最好我想使用URLSession.shared.dataTaskPublisher已经使用的相同的默认后台线程。
所以在 Xcode 生成的标准Persistence.swift中,我只添加了 2 行:
在我的DownloadManager.swift单例中,我调用:
正如您在上面的屏幕截图中看到的那样,这失败了
线程 4:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)
因为我在 Xcode 中添加了以下“启动时传递的参数”:
-com.apple.CoreData.ConcurrencyDebug 1
谁能告诉我,如何newBackgroundContext()
在正确的线程上调用?
更新:
我试图解决我的问题,如下面的代码,但错误是一样的:
更新 2:
我假设当newBackgroundContext()
被调用时,它会占用当前线程,然后您可以从同一个线程使用该上下文......
情况似乎并非如此,我必须调用perform
,performAndWait
或(我已经在 GithubperformBackgroundTask
上更新了我的代码来做到这一点)。
仍然我想知道,如果线程newBackgroundContext
可以与URLSession.shared.dataTaskPublisher
...
swift - iOS Swift DispatchQueue,在将新任务添加到队列之前等待当前任务结束
在将 DispatchQueue 用作 SerialQueue 时,如何在添加新任务之前等待队列上的当前活动进程/任务完成处理,以避免 DispatchQueue 被大量任务阻塞。
在 java 中,我们可以通过使用最大池大小为 1 的 ThreadPoolExecutor 来实现这一点,并在开始另一个任务之前检查内部队列是否为空。
iOS Swift 中是否有类似的东西来实现这一点?
ios - SwiftUI:将 MLKit 结果返回给 SwiftUI 视图不起作用
我有一个具有以下功能的 ScannerService 类:
我从 ScannerView 调用此函数:
}
现在,我返回的是一个空字符串,而不是来自 MLKit TextRecognizer 的结果。经过一些调试,我意识到这与函数在 textRecognizer.process(visionImage) 完成之前完成有关——因为如果我在该函数中放置一个打印语句,它会显示正确的结果。
我试图放置一个 DispatchQueue.main.async,但是,我仍然无法及时获得打印结果——但是,作为线程新手,我不确定在哪里使用它。
当我单击扫描按钮时,结果返回空,但是,当我再次单击扫描按钮时,我可以在控制台中看到之前检测到的文本。
想知道在这里让 detectText 函数完成以便可以在 UI 中使用结果的最佳方法是什么。
swift - 迅速。在其他线程中运行时在原始线程中执行代码
我有使用 SwiftUI 编码的 iOS 应用程序。部分代码来自 Kotlin multiplatform (kmm) 我需要对异步代码做一些工作,它必须在单独的线程中执行。但我也有回调要在线程执行期间运行并且回调失败,因为可变性限制(kotlin 防止对象从一个线程共享到另一个线程)任务是逐行通过 url 读取文件。并向回调对象发送线路问题是回调对象是在外部创建的。
代码与此类似
我启动新线程 Thread {},当我执行 self.callback.OnStart(totalLines: size) 时出现错误“未捕获的 Kotlin 异常:kotlin.native.IncorrectDereferenceException:非法尝试访问非共享”
我不能冻结那个对象,因为它里面有一些计数器,它必须是可变的。
所以,我的问题是:有没有办法在“外部线程”中执行我的回调调用?在我在函数中调用 Thread {} 之前处于活动状态的线程中。
注意,我在这里使用 Thread 只是因为 URLSession.shared.bytes 是异步的,并且需要在线程中运行。无论如何,我调用线程并等待信号量。
在调用 Thread {} 之前,可能类似于 let originalThread = Thread.current 。然后以某种方式使用该值访问前一个线程?
另外,我知道 DispatchQueue 。但我不知道我的函数是否是从主 swift 线程调用的,所以我不会尝试执行 DispatchQueue.main.async { } 因为原始线程可能不同。也许 DispatchQueue 可以用于我用 Thread.current 捕获的原始线程?
你对我有什么想法吗?
swift - 调度组崩溃
我创建了一种从 Firebase 获取用户消息的方法,但是当离开DispatchGroup
应用程序崩溃时会导致此错误Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我不确定我做错了什么。请帮助和解释我。
代码: