由于未捕获的异常“ RLMException”而终止应用程序,原因:“对象已被删除或无效。”

时间:2019-04-26 07:02:36

标签: ios swift4 xcode10.1

我的应用程序具有使用帐单地址的电子商店购买功能。我也有一个账单地址列表,点击列表中的地址单元将进入编辑地址页面。但是,当我运行购买功能并编辑地址,然后返回到“帐单地址列表”页面后,该应用将停止运行。 (如果我不购买就编辑地址,那一切都很好)

错误显示:

Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'

并且:

libc++abi.dylib: terminating with uncaught exception of type NSException

以及 AppDelegate.swift

"Thread 1: signal SIGABRT" 

此行显示错误:

class AppDelegate: UIResponder, UIApplicationDelegate {

这是帐单地址列表代码(其中包含许多帐单地址单元格,点击该单元格将进入编辑地址功能的内部:

import Foundation
import PKHUD

class ManageBillingAddressVC: _BaseViewController {

    @objc var billingAddress: [UserBillingAddress] = [] { //= Address.getAllAddressLists()
        didSet {
            emptyView.isHidden = billingAddress.count != 0
        }
    }

    let viewModel = BillingAddressViewModel()

    @IBOutlet weak var tblBillingAddress: UITableView!
    @IBOutlet weak var emptyView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpNavBarWithAttributes(navtitle: "Manage Billing Address", setStatusBarStyle: .default, isTransparent: false, tintColor: .white, titleColor: Color.Tuna.instance(), titleFont: FontBook.AdobePro.navSize(), isBackHidden: false, isShadowIncluded: true, rightBarButton: [showGoldPlusBtn()])

        viewModelCallBack()
        initTableViews()
        observeAdressUpdateNotification()
    }


    @objc func viewModelCallBack() {

        viewModel.beforeApiCall = {
            HUD.show(.systemActivity)
        }

        viewModel.afterApiCall = {
            HUD.hide()
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.navigationController?.setNavigationBarHidden(false, animated: true)

        fetchBillingAddress()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navigationController?.setNavigationBarHidden(true, animated: true)
    }

    @objc func updateDeliveryAddressTable() {
        fetchBillingAddress()
    }

    @objc func fetchBillingAddress() {
        viewModel.getBillingAddress(success: {
            self.billingAddress.removeAll()
            for address in $0{
                if address.crm_address_order != "postal_address"{
                    self.billingAddress.append(address)
                }
            }
            self.tblBillingAddress.reloadData()
        }) {
            self.showAlert($0)
        }
    }

    @objc func observeAdressUpdateNotification() {
        NotificationCenter.default.addObserver(self, selector: #selector(updateDeliveryAddressTable), name: Constants.billingAddress, object: nil)
    }

    override func rightBarButtonClicked() {

        viewModel.getBillingAddress(success: {
            self.billingAddress.removeAll()
            for address in $0{
                if address.crm_address_order != "postal_address"{
                    self.billingAddress.append(address)
                }
            }

            if self.billingAddress.count >= 3{
                self.showAlert("Addresses are limited to a maximum of 3")
            }else{
                self.pushViewControllerWithSlideUpEffect(vc: UIStoryboard.AddBillingAddress())
            }

            self.tblBillingAddress.reloadData()
        }) {
            self.showAlert($0)
        }
    }

    @objc func initTableViews() {

        tblBillingAddress.register(UINib(nibName : "BillingAddressCell", bundle : nil), forCellReuseIdentifier: "BillingAddressCell")

        tblBillingAddress.dataSource = self
        tblBillingAddress.delegate = self
        tblBillingAddress.separatorStyle = .none
        tblBillingAddress.contentInset = UIEdgeInsetsMake(20, 0, 20, 0)

        tblBillingAddress.rowHeight = UITableViewAutomaticDimension
        tblBillingAddress.estimatedRowHeight = 165 //108

    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

extension ManageBillingAddressVC: DeliveryAddressCellDelegate {

    @objc func didSelectBillingAddress(address: UserBillingAddress, index: Int) {
        guard let vc = UIStoryboard.AddBillingAddress() as? AddBillingAddressVC else { return }
        vc.billingAddress = address
        pushViewControllerWithSlideUpEffect(vc: vc)
    }
}


extension ManageBillingAddressVC: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return billingAddress.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "BillingAddressCell" ) as! BillingAddressCell
        cell.delegate = self
        cell.billingAddress = billingAddress[indexPath.row]
        //cell.address = billingAddress[indexPath.row]
        return cell

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: false)
    }

}

这是我在地址列表代码中的帐单邮寄地址单元格:

import UIKit

class BillingAddressCell: DeliveryAddresCell {

    @objc var billingAddress: UserBillingAddress? {
        didSet {
            billingAddress.flatMap {
                lblName.text = "\($0.salutation ?? ""). \($0.firstname ?? "") \($0.lastname ?? "")"
                lblAddress.text = $0.street?.first
                lblPhoneNo.text = $0.telephone
                lblUnitNo.text = $0.unit_number
                lblStateCountry.text = "\($0.region?.first?.region ?? ""), \($0.postcode ?? "")"

                if let id = $0.country_id, let countryID = Int(id) {
                    lblCountry.text = CountryList.getCountryName(id: countryID)
                }
            }
        }
    }

    override func btnEditTapped(_ sender: UIButton) {
        delegate?.didSelectBillingAddress(address: billingAddress!, index: tag)
    }

}

以下是获取/更新帐单地址的功能:

class UserBillingAddress: UserBillingAddressInformation {

    @objc var id : String?
    @objc var customerID: String?

    required convenience init?(map: Map){
        self.init()
    }

    override func mapping(map: Map){
        super.mapping(map: map)
        id <- map["id"]
        customerID <- map["customer_id"]
    }
}

以下是在购买过程中点击“结帐”按钮后发生的代码:

@IBAction func btnCheckoutTapped(_ sender: UIButton) {

        guard let card = defaultCreditCard, let address = defaultAddress else { return }

        baseViewModel.checkCartLimit(success: { checkLimit in

            if let limitErrors = checkLimit.limit_errors {

                if limitErrors.count > 0 {
                    self.baseViewModel.handleCheckLimitError?(checkLimit)
                } else {

                    guard let processingVC = UIStoryboard.ProcessingOrderVC() as? ProcessingOrderVC else { return }
                    // present processing view
                    processingVC.modalPresentationStyle = .overCurrentContext
                    processingVC.defaultAddress = address
                    processingVC.defaultCreditCard = card
                    processingVC.isSkyDollarPurchaseForMembership = self.isSkyDollarPurchaseForMembership
                    processingVC.isMembershipProduct = self.isMembershipProduct
                    processingVC.isFullSkyDollarPurchase = self.isFullSkyDollarPurchase
                    self.present(processingVC, animated: true)
                }

            } else {

                guard let processingVC = UIStoryboard.ProcessingOrderVC() as? ProcessingOrderVC else { return }
                // present processing view
                processingVC.modalPresentationStyle = .overCurrentContext
                processingVC.defaultAddress = address
                processingVC.defaultCreditCard = card
                processingVC.isSkyDollarPurchaseForMembership = self.isSkyDollarPurchaseForMembership
                processingVC.isMembershipProduct = self.isMembershipProduct
                self.present(processingVC, animated: true)
            }

        }, failure: { (errorMessage) in
            self.showAlert(errorMessage)
        })
    }

这是点击结帐按钮后的购买处理代码:

import UIKit

class ProcessingOrderVC: UIViewController {

    @IBOutlet weak var orderProcessingStackView: UIStackView!
    @IBOutlet weak var orderProcessErrorStackView: UIStackView!

    @IBOutlet weak var btnOkay: UIButton!
    @IBOutlet weak var lblError: UILabel!

    @objc var isMembershipProduct : Bool = false
    @objc var isSkyDollarPurchaseForMembership : Bool = false
    @objc var isFullSkyDollarPurchase: Bool = false

    let checkoutViewModel = CheckoutStep2ViewModel()
    @objc var defaultAddress = Address()
    @objc var defaultCreditCard = CreditCardData()

    override func viewDidLoad() {
        super.viewDidLoad()
        let attributedTitle = NSAttributedString(string: "TRY AGAIN", attributes: [NSAttributedStringKey.kern: 1.3, NSAttributedStringKey.font : FontBook.Bold.of(size: 13.0), NSAttributedStringKey.foregroundColor: UIColor.white])
        btnOkay?.setAttributedTitle(attributedTitle, for: .normal)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        if isSkyDollarPurchaseForMembership{
            self.checkoutViewModel.placeOrderWithSkyDollarForMembership(address: defaultAddress, success: { orderID in
                (UIStoryboard.CheckoutStep3VC() as? CheckoutStep3VC).flatMap {
                    $0.orderID = orderID
                    $0.hero.modalAnimationType = .fade
                    self.present($0, animated: false, completion: nil)
                }
            }) { (error) in
                self.showError()
            }
        }else{
            self.checkoutViewModel.placeOrder(address: defaultAddress, card: defaultCreditCard, isFullSkyDollarPurchase: isFullSkyDollarPurchase, success: { orderID in
                (UIStoryboard.CheckoutStep3VC() as? CheckoutStep3VC).flatMap {
                    $0.orderID = orderID
                    $0.hero.modalAnimationType = .fade
                    self.present($0, animated: false, completion: nil)
                }
            }) { (error) in
                self.showError()
            }
        }


    }

    @IBAction func btnCloseTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }

    @IBAction func btnOkayTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }

    @objc func showError() {
        orderProcessErrorStackView.isHidden = false
        orderProcessingStackView.isHidden = true
    }

}

这是defaultAddress变量和地址类:

@objc var defaultAddress = Address()

class Address : Object, Mappable{

    @objc dynamic var id: Int = 0
    @objc dynamic var customerId: Int = 0
    @objc dynamic var region: Region? = nil
    @objc dynamic var region_id: Int = 0
    @objc dynamic var countryId: String = ""
    let streets = List<Street>()
    @objc dynamic var telephone: String = ""
    @objc dynamic var postcode: String = ""
    @objc dynamic var city: String = ""
    @objc dynamic var prefix: String = ""
    @objc dynamic var company: String = ""
    @objc dynamic var firstname: String = ""
    @objc dynamic var lastname: String = ""
    @objc dynamic var defaultShipping: Bool = false
    @objc dynamic var defaultBilling: Bool = false
    var addressAttributes = List<AddressAttributes>()


    required convenience init?(map: Map){
        self.init()
    }

没错,购买过程不会更新地址,但是,如果我不购买,那么编辑地址就不会有错误。该错误仅在进行购买过程之后发生。我真的不知道发生了什么谁能建议可能是什么问题?

我在iOS上还很新,所以请更精确地解决问题。非常感谢你!

0 个答案:

没有答案