iOS应用程序崩溃与EXC_BAD_ACCESS(代码= 1,地址= 0x0)

时间:2015-05-26 18:34:52

标签: ios swift

我的代码中有一个问题,我无法弄清楚。当我运行我的应用程序时,有时会加载我的单元格,有时会立即崩溃。我相信我的问题出在我的cellForRowInIndexPath

我的错误在cellForRowInIndexPath

cellDrawer.insertDescriptionLabel(cell, text: offer.title)

这是我的错误:

Thread 1: EXC_BAD_ACCESS(code=1,address=0x0)

这是我的代码:

import UIKit

class ProdutsViewController: UIViewController, UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating{

    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var tableViewFooter: MyFooter!

    var searchResults:[Offer] = []
    var resultSearchController = UISearchController()
    var loading = false


    lazy var offers:[Offer]? = {
        print("lazy of offers\n")
        var restConnection = RestFulConnection()
        restConnection.fetchDataFromServer()
        return DataBaseChecker.getDataFromDatabase()
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        print("viewDidLoad\n")
        self.resultSearchController = ({
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()

            self.tableView.tableHeaderView = controller.searchBar

            return controller
        })()

        // Reload the table
        self.tableView.reloadData()

        self.tableViewFooter.hidden = true

        loadSegment()
    }

    class MyDataProvider {

        class func getInstance() -> MyDataProvider {
            print("getInstance of MyDataProvider\n")
            return MyDataProvider() //return a new instance since class vars not supported yet
        }

        func requestData(listener:([Offer]) -> ()) {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                //simulate delay
                sleep(1)
                print("requestData of MyDataProvider\n")
                //generate items

                var restConnection = RestFulConnection()
                restConnection.fetchDataFromServer()
                var arr = DataBaseChecker.getDataFromDatabase()

                //call listener in main thread
                dispatch_async(dispatch_get_main_queue()) {
                    listener(arr)
                }
            }
        }
    }
    func scrollViewDidScroll(scrollView: UIScrollView) {
        print("scrollViewDidScroll\n")
        let currentOffset = scrollView.contentOffset.y
        let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height

        if (maximumOffset - currentOffset) <= 40 {
            print("IF of scrollViewDidScroll\n")
            loadSegment()
        }
    }

    func loadSegment() {
        print("loadSegment\n")
        if (!self.loading) {

            self.setLoadingState(true)
            print("IF of loadSegment\n")

            MyDataProvider.getInstance().requestData(
                {(offers:[Offer]) -> () in
                    print("block of requestData on method loadSegment\n")
                    for offer:Offer in offers {
                        print("for of loadSegment\n")
                        if(DataBaseChecker.isItNew(offer)){
                        self.offers?.append(offer)
                        }
                    }

                    self.tableView.reloadData()

                    self.setLoadingState(false)
            })
        }
    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
        print("didReceiveMemoryWarning\n")
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = self.tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! UITableViewCell
        print("CellForRowAtIndexPath\n")
//        var offer:Offer?
//            if (self.resultSearchController.active) {
//                offer = searchResults[indexPath.row]
//            } else {
//                offer = offers?[indexPath.row]
//            }
        if(offers != nil){
            var offer:Offer = offers![indexPath.row]
            print("IF of offers not nil, offers = \(offer.title)\n")
                var cellDrawer = CellDrawer()
                if (cell.viewWithTag(1) == nil){
                    cellDrawer.createWhiteContentInCell(cell)
                }
                cellDrawer.insertImageInCell(offer.images, cell: cell)
                cellDrawer.insertBlackContentInCell(cell)
                cellDrawer.insertDescriptionLabel(cell, text: offer.title)
                cellDrawer.insertLocalLabel(cell, text: "String Sample")
                cellDrawer.insertOldPriceLabel(cell, number: offer.oldPrice)
                //cellDrawer.insertFromPriceLabel(cell, text: "a partir de")
                cellDrawer.insertNewPriceLabel(cell,number:offer.newPrice)
        }
        return cell
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("NumberOfRowsInSection\n")
        if(offers != nil){
            print("IF offers not nil of NumberOfRowsInSection\n")
            if (self.resultSearchController.active) {
                print("IF2 of NumberOfRowsInSection\n")
                return searchResults.count
            } else {
                print("ELSE of NumberOfRowsInSection, offers count = \(offers!.count)\n")
                return offers!.count
            }
        }
        return 0
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        print("numberOfSectionsInTableView\n")
        if(offers != nil && offers!.count >= 1){
            print("if of numberOfSectionsInTableView\n")
                return 1
        }
        return 0
    }

    func setLoadingState(loading:Bool) {
        print("setLoadingState\n")
        self.loading = loading
        self.tableViewFooter.hidden = !loading
    }
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        print("heightForRowAtIndexPath\n")
        return 235
    }


    func updateSearchResultsForSearchController(searchController: UISearchController)
    {
        print("updateSearchResultsForSearchController\n")
        if(offers != nil){
            print("if of updateSearchResultsForSearchController")
            searchResults.removeAll(keepCapacity: false)

            let searchPredicate = NSPredicate(format: "title CONTAINS[c] %@", searchController.searchBar.text)
            let array = NSArray(array: offers!)
            array.filteredArrayUsingPredicate(searchPredicate)
            self.searchResults = array as! [Offer]

            self.tableView.reloadData()
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
       print("prepareForSegue\n")
        if segue.identifier == "detailsSegue" {
            print("IF of prepareForSegue\n")
            let DetailTVC = segue.destinationViewController as! DetailsTVC
            if sender as! UITableView == self.resultSearchController.active {
                print("IF2 of prepareForSegue\n")
                let indexPath = self.tableView.indexPathForSelectedRow()!
                let offer = self.searchResults[indexPath.row]
                DetailTVC.offer = offer
            } else {
                print("Else of prepareForSegue\n")
                let indexPath = self.tableView.indexPathForSelectedRow()!
                let offer = self.offers![indexPath.row]
                DetailTVC.offer = offer
            }
        }
    }

}

希望有人可以提供帮助。

4 个答案:

答案 0 :(得分:1)

如果offer.title不是nil,那么cellDrawer可能会在不再有效的单元格上执行某些操作。

设置断点并使用调试器中的po(print object)检查offer.title属性。

当抽屉试图加载标题时,也可能是正在更新商品数组的竞争条件。

答案 1 :(得分:0)

看起来您没有为重用标识符注册类。在viewDidLoad函数中应该有:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")

答案 2 :(得分:0)

在这种情况下,我认为报价本身是零,当你尝试获得title属性/ ivar时,你会遇到崩溃。

答案 3 :(得分:0)

我遇到了同样错误的非常类似的问题。最后我发现了错误,这是因为自定义类(MyMapView类)的@IBOutlet。在UI中使用自定义类时,需要在Interface Builder的Identity Inspector中指明该类。它解决了我的问题。

enter image description here