线程1:EXC_BAD_ACCESS(代码= 2,地址= 0x16d0f3ff0)

问题描述 投票:0回答:1

我正在开发一个应用程序(在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错误:...

ios swift4.2
1个回答
-1
投票

从视图中添加异常断点>导航器>显示断点导航器。在加号(+)中,您可以添加例外断点。这将进入尝试访问不存在的值的确切代码。

© www.soinside.com 2019 - 2024. All rights reserved.