首页 > 解决方案 > libc++abi.dylib:以 NSException (lldb) 类型的未捕获异常终止:下拉菜单

问题描述

所以我最近遇到了我们团队无法解决的 Sigabrt 崩溃。它涉及到 segue 崩溃。当我从信息视图控制器按下学校规则按钮时,它会推送(执行 segue)到学校规则视图控制器。但是,当我按下后退按钮(在顶部的导航栏上)时,它会返回到信息视图控制器,但随后会崩溃。下面是我的崩溃日志和视图控制器:

注意:我检查了所有正常的 Sigabrt 崩溃,包括链接的插座、Segue 标识符等。

Application did finish launching
2018-04-29 11:13:47.156002+0800 DBS[6288:361798] Simulator user has requested new graphics quality: 100
DidDisappear ()
true
(8.0, 8.0, 375.0, 812.0)
(8.0, 145.111111111111, 359.0, 521.777777777778)
2018-04-29 11:14:19.188187+0800 DBS[6288:361798] [general] Caught exception during autorelease pool drain NSGenericException: Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600000669700 "DBS.dropDownView:0x7fcda1537890.top"> and <NSLayoutYAxisAnchor:0x60000066a300 "DBS.dropDownBtn:0x7fcda1538510'▼ Introduction'.bottom"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal. userInfo: (null)
2018-04-29 11:14:19.203034+0800 DBS[6288:361798] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600000669700 "DBS.dropDownView:0x7fcda1537890.top"> and <NSLayoutYAxisAnchor:0x60000066a300 "DBS.dropDownBtn:0x7fcda1538510'▼ Introduction'.bottom"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010adbe1e6 __exceptionPreprocess + 294
    1   libobjc.A.dylib                     0x000000010a00c031 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010ae33975 +[NSException raise:format:] + 197
    3   DBS                                 0x0000000107f64206 _T03DBS11dropDownBtnC18didMoveToSuperviewyyF + 566
    4   DBS                                 0x0000000107f644b4 _T03DBS11dropDownBtnC18didMoveToSuperviewyyFTo + 36
    5   UIKit                               0x000000010c5f7400 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 899
    6   UIKit                               0x000000010c5f6fea -[UIView(Hierarchy) _postMovedFromSuperview:] + 808
    7   UIKit                               0x000000010c5f4e9e __UIViewWasRemovedFromSuperview + 169
    8   UIKit                               0x000000010c5f4990 -[UIView(Hierarchy) removeFromSuperview] + 479
    9   UIKit                               0x000000010c5ddc67 -[UIView dealloc] + 508
    10  libobjc.A.dylib                     0x000000010a0211b2 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 860
    11  CoreFoundation                      0x000000010ad08136 _CFAutoreleasePoolPop + 22
    12  CoreFoundation                      0x000000010ad44eae __CFRunLoopRun + 2350
    13  CoreFoundation                      0x000000010ad4430b CFRunLoopRunSpecific + 635
    14  GraphicsServices                    0x000000011396ca73 GSEventRunModal + 62
    15  UIKit                               0x000000010c53f0b7 UIApplicationMain + 159
    16  DBS                                 0x0000000107f68507 main + 55
    17  libdyld.dylib                       0x000000010f37d955 start + 1
    18  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

下面是我的 DropDownButton 视图控制器:

import UIKit

protocol dropDownProtocol {
    func dropDownPressed(string : String)
}

class dropDownBtn: UIButton, dropDownProtocol {

    func dropDownPressed(string: String) {
        self.setTitle("▼ \(string)", for: .normal)
        self.titleLabel?.adjustsFontSizeToFitWidth = true
        self.dismissDropDown()
    }

    var dropView = dropDownView()

    var height = NSLayoutConstraint()


    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = UIColor.lightGray

        dropView = dropDownView.init(frame: CGRect.init(x: 8, y: 100, width: 0, height: 0))
        dropView.delegate = self
        dropView.translatesAutoresizingMaskIntoConstraints = false
    }

    override func didMoveToSuperview() {
        self.superview?.addSubview(dropView)
        self.superview?.bringSubview(toFront: dropView)
        dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        height = dropView.heightAnchor.constraint(equalToConstant: 0)
    }

    var isOpen = false
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if isOpen == false {

            isOpen = true

            NSLayoutConstraint.deactivate([self.height])

            //            if self.dropView.tableView.contentSize.height > 400 {
            //                self.height.constant = 400
            //            } else {
            //                self.height.constant = self.dropView.tableView.contentSize.height
            //            }
            self.height.constant = self.dropView.tableView.contentSize.height+8

            NSLayoutConstraint.activate([self.height])

            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
                self.dropView.layoutIfNeeded()
                self.dropView.center.y += self.dropView.frame.height / 2
            }, completion: nil)

        } else {
            isOpen = false

            NSLayoutConstraint.deactivate([self.height])
            self.height.constant = 0
            NSLayoutConstraint.activate([self.height])
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
                self.dropView.center.y -= self.dropView.frame.height / 2
                self.dropView.layoutIfNeeded()
            }, completion: nil)

        }
    }

    func dismissDropDown() {
        isOpen = false
        NSLayoutConstraint.deactivate([self.height])
        self.height.constant = 0
        NSLayoutConstraint.activate([self.height])
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
            self.dropView.center.y -= self.dropView.frame.height / 2
            self.dropView.layoutIfNeeded()
        }, completion: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

标签: iosswiftxcodeswift4sigabrt

解决方案


您的didMoveToSuperview函数假定仅在将视图添加到其父视图时才调用它。但是当它从其父视图中删除时也会调用它。如果您查看堆栈跟踪,您可以看到在删除视图时发生了崩溃。您需要更新您的didMoveToSuperview,以便它仅在添加时运行代码,而不是在删除时运行。

override func didMoveToSuperview() {
    if let superview = self.superview {
        superview.addSubview(dropView)
        superview.bringSubview(toFront: dropView)
        dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        height = dropView.heightAnchor.constraint(equalToConstant: 0)
    }
}

推荐阅读