Висячий указатель при одновременном доступе для чтения/записи к массивуIOS

Программируем под IOS
Ответить
Anonymous
 Висячий указатель при одновременном доступе для чтения/записи к массиву

Сообщение Anonymous »

Я пытаюсь понять, что не так в моем подходе к доступу к массиву. В моем приложении я получил несколько невоспроизводимых сбоев с EXC_BAD_ACCESS KERN_INVALID_ADDRESS (некоторые не с 0 адресом). Я предположил, что это связано с доступом для чтения/записи к массиву. Чтобы разобраться, я написал код, немного похожий на код приложения для детской площадки:

Код: Выделить всё

import Foundation
import CoreBluetooth

let requiredServices: [CBUUID] = [
CBUUID(string: "180A"),
CBUUID(string: "280A"),
CBUUID(string: "380A"),
CBUUID(string: "480A"),
CBUUID(string: "580A"),
CBUUID(string: "680A"),
CBUUID(string: "780A"),
CBUUID(string: "880A"),
]

// Array to investigate
var availableServices = [CBUUID]()

let queues = [
DispatchQueue(label: "test0"),
DispatchQueue(label: "test1"),
DispatchQueue(label: "test2"),
DispatchQueue(label: "test3"),
DispatchQueue(label: "test4"),
DispatchQueue(label: "test5"),
DispatchQueue(label: "test6"),
DispatchQueue(label: "test7"),
DispatchQueue(label: "test8"),
DispatchQueue(label: "test9"),
DispatchQueue(label: "test10")
]

func mainTest() {

print(">>>> Main test")

for i in 0...100 {
for j in 1...10 {
queues[0].async {
for _ in 1...100 {
// Write operation
doAppendAndClear()
}
}
queues[j].async {
for k in 1...100 {
// Read operation
tryToRead()
if i == 100, j == 10, k == 100 {
print(">>>> The end")
}
}

}
}
}
}

func doAppendAndClear() {
availableServices.append(CBUUID(string: "180A"))
availableServices.append(CBUUID(string: "280A"))

availableServices = []

availableServices.append(CBUUID(string: "380A"))
availableServices.append(CBUUID(string: "480A"))

availableServices = []

availableServices.append(CBUUID(string: "580A"))
availableServices.append(CBUUID(string: "680A"))

availableServices = []

availableServices.append(CBUUID(string: "780A"))
availableServices.append(CBUUID(string: "880A"))

availableServices = []
}

func tryToRead() {
let services = availableServices
var available = true
requiredServices.forEach({ available = available && services.contains($0)})
}

mainTest()
Я получил это предупреждение на игровой площадке и такое же предупреждение, когда вставил тест в код приложения:

Объект 0x600000e631e0 класса _ContigousArrayStorage освобожден с ненулевым счетчиком сохранения 2. Deinit этого объекта или что-то, вызванное из него, возможно, создало сильную ссылку на себя, которая пережила deinit, что привело к висячей ссылке

Кроме того, у меня возникали сбои в приложении, когда я вставлял туда проверенный код. Это произошло в методе tryToRead(), в последней его строке:

Код: Выделить всё

thread #17, queue = 'test5', stop reason = EXC_BAD_ACCESS (code=1, address=0x97b30d800)
frame #0: 0x000000018c3f2244 libobjc.A.dylib`objc_retain_x8 + 16
frame #1: 0x0000000193172210 libswiftCore.dylib`swift::metadataimpl::ValueWitnesses::initializeWithCopy(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata const*) + 28
frame #2: 0x0000000192ddf844 libswiftCore.dylib`Swift.Array.subscript.read : (Swift.Int) -> τ_0_0 + 232
frame #3: 0x0000000192ddf728 libswiftCore.dylib`protocol witness for Swift.Collection.subscript.read : (τ_0_0.Index) -> τ_0_0.Element in conformance Swift.Array : Swift.Collection in Swift + 68
frame #4: 0x0000000192e3fad0 libswiftCore.dylib`protocol witness for Swift.IteratorProtocol.next() -> Swift.Optional in conformance Swift.IndexingIterator : Swift.IteratorProtocol in Swift + 676
frame #5: 0x0000000192f88164 libswiftCore.dylib`Swift.Sequence.contains(where: (τ_0_0.Element) throws -> Swift.Bool) throws -> Swift.Bool + 664
frame #6: 0x0000000192e767ec libswiftCore.dylib`Swift.Sequence< where τ_0_0.Element: Swift.Equatable>.contains(τ_0_0.Element) -> Swift.Bool + 156
* frame #7: 0x0000000104d2a3d4 MyApp`closure #1 in ContainerVC.tryToRead($0=0x0000000303fde400, available=true, services=2 values) at ContainerVC.swift:202:58
frame #8: 0x0000000104d310d4 MyApp`partial apply for closure #1 in ContainerVC.tryToRead() at :0
frame #9: 0x0000000192ea2e70 libswiftCore.dylib`Swift.Sequence.forEach((τ_0_0.Element) throws -> ()) throws -> () + 756
frame #10: 0x0000000104d2a2dc MyApp`ContainerVC.tryToRead(self=0x00000001420c7800) at ContainerVC.swift:202:26
frame #11: 0x0000000104d29c2c MyApp`closure #2 in ContainerVC.mainTest(self=0x00000001420c7800, i=0, j=5) at ContainerVC.swift:166:30
Исходный сбой в Firebase имеет разные верхние строки в стеке:

Код: Выделить всё

Crashed: com.apple.main-thread
0  libswiftCore.dylib             0x2f7178 _swift_release_dealloc + 16
1  libswiftCore.dylib             0x2f8060 bool swift::RefCounts::doDecrementSlow(swift::RefCountBitsT, unsigned int) + 184
Итак, вопрос в том, почему появились эти свисающие пуанты? Также, возможно, вы знаете, как избежать этого при выполнении чтения/записи в массив?


Подробнее здесь: https://stackoverflow.com/questions/783 ... s-to-array
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»