线程 1:EXC_BAD_ACCESS(代码=2,地址=0x16d0f3ff0)
Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)
我正在开发一个应用程序(在 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 函数内)之前跳过错误
在 Debug Navigator 中,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
有人知道如何解决吗?
谢谢!
在我的例子中,这个错误发生在我创建循环引用时。
我创建了一个 Column 对象,并在列初始值设定项中计算出要创建的列数。为了计算该列表,getter 初始化了一个列数组。
通过更改 LinkedList 的 removeAll 方法解决了以下问题:
public func removeAll() {
while head != nil {
removeTail()
}
}
public func removeTail() {
guard let tail = tail else {return}
if let prev = tail.previous {
prev.next = nil
self.tail = prev
} else {
self.head = nil
self.tail = nil
}
count -= 1
if count < 0 { count = 0}
}
我正在开发一个应用程序(在 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 函数内)之前跳过错误
在 Debug Navigator 中,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
有人知道如何解决吗?
谢谢!
在我的例子中,这个错误发生在我创建循环引用时。
我创建了一个 Column 对象,并在列初始值设定项中计算出要创建的列数。为了计算该列表,getter 初始化了一个列数组。
通过更改 LinkedList 的 removeAll 方法解决了以下问题:
public func removeAll() {
while head != nil {
removeTail()
}
}
public func removeTail() {
guard let tail = tail else {return}
if let prev = tail.previous {
prev.next = nil
self.tail = prev
} else {
self.head = nil
self.tail = nil
}
count -= 1
if count < 0 { count = 0}
}