同时访问——我怎样才能知道正在访问什么?

Sam*_*ami 5 xcode swift

我的应用程序崩溃并显示以下消息:

同时访问0x7fa4a8e10d68,但修改需要独占访问。

我怎样才能找到0x7fa4a8e10d68对应的内容?当我尝试搜索它时,它没有出现,请参阅我附加的图片。 在此输入图像描述

根据提供的屏幕截图,如何知道是否gallaryModel存在galleries[indexPath.row]问题?

Ham*_*ish 6

1. 简单案例

\n\n

您可以通过几种方法来调查此问题。在简单的情况下,运行时错误消息可以为您提供足够的线索来找出冲突是什么。例如,在您的情况下,错误消息通知您当前访问是修改\ xe2\x80\x93 因此在如下行上:

\n\n
galleryModel.requestNameUpdate(for: galleries[indexPath.row], with: resulting)\n
Run Code Online (Sandbox Code Playgroud)\n\n

假设galleryModel是 值类型,并且requestNameUpdatemutating方法,则冲突必须与galleryModel,因为该行上的所有其他访问都是读取。

\n\n
\n\n

2.查看之前的访问情况

\n\n

在大多数情况下,您可以使用的另一个选项是查看先前访问发生的位置,这应该为您提供足够的信息来推断哪个变量发生冲突。为了进行演示,让我们考虑以下程序:

\n\n
func bad(_ x: inout [String], _ body: () -> Void) {\n  body()\n}\n\nvar s = [String]()\nvar a = "hello"\n\ndo {\n  bad(&s) {\n    s.append(a) // Thread 1: Simultaneous accesses to 0x100556a50 [...]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 Xcode 中运行此命令将暂停上面一行的执行:

\n\n

在此输入图像描述

\n\n

如果我们点击堆栈跟踪中的“上一次访问(修改)开始于”(以红色突出显示),Xcode 将向我们显示上一次访问开始的行:

\n\n

在此输入图像描述

\n\n

在这个例子中,有足够的信息来知道该变量s是冲突的变量。

\n\n
\n\n

3. 检查变量地址

\n\n

在更一般的情况下,您可以检查变量的内存地址以确定哪个变量发生冲突。继续前面的示例,我们可以右键单击变量查看器中显示的任何变量,然后通过选择“查看 [...] 的内存”来调出内存查看器:

\n\n

在此输入图像描述

\n\n

这将为我们提供变量的地址(以红色突出显示)。如果此地址与错误消息中显示的地址匹配(例如在本例中),我们就发现了冲突。

\n\n
\n\n

4、拆解

\n\n

另一种选择是查看反汇编代码,看看如果没有发生冲突,我们会尝试做什么。disassemble -a <address>我们可以通过运行并使用上面的堆栈帧的地址在调试器中执行此操作swift_beginAccess

\n\n

在此输入图像描述

\n\n

然后,您想要导航到上面以红色突出显示的偏移量,在本例中为+ 174,这为我们提供了调用后的位置swift_beginAccess

\n\n

在此输入图像描述

\n\n

然后我们可以看到,如果没有冲突,我们就会调用Array它的append(_:)方法 (at ),因为这是由/对保护的调用。由此我们可以推断,冲突的变量一定是。+ 193swift_beginAccessswift_endAccesss

\n