My app is crashing with this message:
Simultaneous accesses to 0x7fa4a8e10d68, but modification requires exclusive access.
How can I find out what 0x7fa4a8e10d68
corresponds to? It's not coming up when I try to search for it, see the image I attached.
Based on what is provided is the screenshot, how would one know whether gallaryModel
or galleries[indexPath.row]
is the issue?
There are a few ways you can go about investigating this. In simple cases, the runtime error message can give you enough of a clue to work out what the conflict is. For example, in your case the error message informs you that the current access is a modification – therefore on a line like this:
galleryModel.requestNameUpdate(for: galleries[indexPath.row], with: resulting)
Assuming galleryModel
is a value type, and requestNameUpdate
is a mutating
method, the conflict must be with galleryModel
, as all other accesses on that line are reads.
Another option you can use in most cases is to look at where the previous access occurred, which should give you enough information to deduce which variable is in conflict. To demonstrate, let's consider the following program:
func bad(_ x: inout [String], _ body: () -> Void) {
body()
}
var s = [String]()
var a = "hello"
do {
bad(&s) {
s.append(a) // Thread 1: Simultaneous accesses to 0x100556a50 [...]
}
}
Running this in Xcode will pause the execution on the above line:
If we click on "previous access (a modification) started at" in the stack trace (highlighted in red), Xcode will show us the line where the previous access started:
And in this example, that's enough information to know that the variable s
is the one in conflict.
In more general cases, you can inspect the memory addresses of variables in order to determine which one is conflicting. Continuing from the previous example, we can right click on any of the shown variables in the variable viewer and bring up the memory viewer by selecting "View memory of [...]":
Which will give us the address of the variable (highlighted in red). If this address matches the one shown in the error message (such as in this case), we've found the conflict.
Another option is to view the disassembly to see what we would have been attempting to do if the conflict hadn't taken place. We can do this in the debugger by running disassemble -a <address>
and using the address of the stack frame above swift_beginAccess
:
You then want to navigate to the offset highlighted above in red, in this case + 174
, which gives us the location after the call to swift_beginAccess
:
We can then see that we would have been calling Array
's append(_:)
method (at + 193
) if it hadn't been for the conflict, as that's the call being guarded by the swift_beginAccess
/swift_endAccess
pair. From that we can deduce that the variable in conflict must have been s
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With