Я разрабатываю приложение (в XCode
версии 11.2 и Swift 4.2), в котором я заполняю LinkedList и после работы с ним, удаляя составляющие его элементы, выдает Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
. Ошибка возникает даже без работы с элементами в списке, просто добавляя их и пытаясь устранить их, ошибка уже возникает. Тесты, которые я выполняю на iPhone с IOS version 11.4.1
Реализация LinkedList выглядит следующим образом:
import Foundation
public class Node<T> {
var value: T
var next: Node<T>?
weak var previous: Node<T>?
init(value: T) {
self.value = value
} // init
} // Node
public class LinkedList<T> {
private var head: Node<T>?
private var tail: Node<T>?
public private(set) var count: Int = 0
public init() { } // init
public var isEmpty: Bool {
return self.head == nil
} // isEmpty
public var first: Node<T>? {
return self.head
} // first
public var last: Node<T>? {
return self.tail
} // last
public func nodeAt(index: Int) -> Node<T>? {
if index >= 0 {
var node = self.head
var i = index
while node != nil {
if i == 0 {
return node
} // if
i -= 1
node = node!.next
} // while
} // if
return nil
} // nodeAt
public func removeAll() {
self.head = nil
self.tail = nil
self.count = 0
} // removeAll
public func remove(node: Node<T>?) -> String {
if isEmpty {
return String("ERROR: Empty list, nothing to remove.")
} // if
guard node != nil else {
return String("ERROR: Invalid node, nothing to remove.")
} // guard
let prev = node?.previous
let next = node?.next
if next != nil && prev == nil {
self.head = next
next?.previous = nil
} else if next != nil && prev != nil {
prev?.next = next
next?.previous = prev
} else if next == nil && prev != nil {
self.tail = prev
prev?.next = nil
} // if
node?.previous = nil
node?.next = nil
self.count -= 1
return String("Successfully removed node: \(node!.value)")
} // remove
func enqueue(value: T) {
let newNode = Node(value: value)
if let tailNode = self.tail {
newNode.previous = tailNode
tailNode.next = newNode
} else {
self.head = newNode
} // else
self.tail = newNode
self.count += 1
}
func enqueue_first(value: HexRecord) {
let newNode = Node(value: value)
if let headNode = self.head {
newNode.next = headNode
headNode.previous = newNode
}
self.head = newNode
self.count += 1
}
func dequeue() -> T? {
let element = self.head?.value
self.head = self.head?.next
self.count -= 1
return element
}
} // LinkedList
Узлы этого типа HexRecord:
public class HexRecord
{
private var length: Int = 0
private var address: Int64 = 0
private var type: Int32 = 0
private var data = [UInt8] ()
private var checksum: UInt8 = 0
init()
{
}
public func getAddress() -> Int64 {
return address;
}
public func getType() -> Int32 {
return type;
}
public func getData() -> [UInt8] {
return data;
}
public func getLength() -> Int {
return length;
}
public func getChecksum() -> UInt8 {
return checksum;
}
public func setAddress(address: Int64) {
self.address = address;
}
public func setData(data: [UInt8]) {
self.data = data;
}
public func setLength(length: Int) {
self.length = length;
}
public func setType(type: Int32) {
self.type = type;
}
public func setChecksum(checksum: UInt8) {
self.checksum = checksum;
}
}
Используется следующим образом:
func tratar_registros() {
var records = LinkedList<HexRecord>();
....
let data_line: HexRecord? = try parseRecord(line: line) // parseRecord convert String to HexRecord
if (data_line != nil)
{
records.enqueue(value: data_line!)
}
....
records.removeAll(); //Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)
} // Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0) if there is no line records.removeAll();
С отладчиком я вижу, что ошибка возникает при назначении значения nil для self.head. Непосредственно перед тем, как self.head имеет правильные значения, оно становится равным nil, и ошибка пропускается до достижения следующей инструкции (в функции removeAll)
В Навигаторе отладки в stackTrace последние 2 функции, где ошибкавидел:
libobjc.A.dylib`_object_remove_assocations:
0x180d11eec <+0>: sub sp, sp, #0x70 ; =0x70
-> 0x180d11ef0 <+4>: stp x26, x25, [sp, #0x20] //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
0x180d11ef4 <+8>: stp x24, x23, [sp, #0x30]
libswiftCore.dylib`_swift_release_:
0x104e18d1c <+180>: bl 0x104e1a37c ; bool swift::RefCounts<swift::SideTableRefCountBits>::doDecrement<(swift::PerformDeinit)1>(unsigned int)
-> 0x104e18d20 <+184>: ldp x29, x30, [sp], #0x10. //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
0x104e18d24 <+188>: ret
У кого-нибудь есть идеи, как это решить?
Спасибо!