我正在开发一个应用程序(在XCode版本11.2和Swift 4.2中),在其中填写了LinkedList,并在使用它后,删除了组成该应用程序的元素,从而产生线程1错误:EXC_BAD_ACCESS(代码= 2,地址= 0x16d0f3ff0 )。即使不使用列表中的项目,也会发生错误,只需添加它们并尝试消除它们,就已经发生了错误。我正在使用IOS版本11.4.1的iPhone进行的测试]
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中,看到错误的最后两个函数:
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
有人知道如何解决吗?
谢谢!
我正在开发一个应用程序(在XCode版本11.2和Swift 4.2中),在其中填写了LinkedList,并在使用它之后,删除了组成该应用程序的元素,从而产生线程1错误:...
从视图中添加异常断点>导航器>显示断点导航器。在加号(+)中,您可以添加例外断点。这将进入尝试访问不存在的值的确切代码。