在Crashlytics的tableView中的cellForRowAtIndexPath中获取崩溃

时间:2016-09-12 01:18:06

标签: ios swift uitableview crash crashlytics

我在Crashlytics上遇到了奇怪的崩溃,它在代码中被评论显示崩溃。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    if indexPath.row >= collectionArrayApiObject.collectionsArray.count {
        return UITableViewCell(frame: CGRectZero)
    }

    var tableViewCell:CollectionsTableViewCell? = tableView.dequeueReusableCellWithIdentifier("collectionsCell") as? CollectionsTableViewCell
    if (tableViewCell == nil) {
        tableViewCell = CollectionsTableViewCell(style: .Default, reuseIdentifier: "collectionsCell")
    }
    // Got crash in below line
    let collectionObject = collectionArrayApiObject.collectionsArray[indexPath.row]
    tableViewCell!.setCollection(collectionObject)

    return tableViewCell!
}

这是我得到的堆栈跟踪..

Stack Traces

但是没有理解为什么这甚至发生了?我已经检查了

index.row >= collectionArrayApiObject.collectionsArray.count

所以它不应该是超出范围的索引。任何人都可以给我一个可能发生这种情况的案例吗?

注意:直到现在只发生了一个用户,但为什么会发生这种情况呢?

整个表视图控制器:

import UIKit

class CollectionsViewController: CUIBaseViewController, CollectionArrayApiObjectDelegate, UITableViewDataSource, UITableViewDelegate, UIViewControllerPreviewingDelegate {
var collectionsTableView : UITableView?
var collectionArrayApiObject : CollectionArrayApiObject = CollectionArrayApiObject()
var headerSearchButton : UIBarButtonItem?
var cityId: String?

required init?(coder aDecoder: NSCoder) {
    fatalError("NSCoding not supported")
}

override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

convenience init(CityId: String? = nil) {
    self.init(nibName: nil, bundle: nil)
    self.cityId = CityId
    self.view.backgroundColor = Colors.white()
}

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    self.setUpHeaderView()
    self.createTableView()
    self.getData()
    self.listenToNotifications()
    self.automaticallyAdjustsScrollViewInsets = false
    if #available(iOS 9.0, *) {
        registerForPreviewingWithDelegate(self, sourceView: collectionsTableView!)
    }
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

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

func listenToNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(CollectionsViewController.cityChanged), name: Constants.NOTIFIICATION_LOCATION_CHANGED_CITY, object: nil)
}

func cityChanged() {
    self.getData()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    collectionsTableView?.frame = CGRectMake(0, Constants.NAV_BAR_HEIGHT, self.view.width, self.view.height - Constants.NAV_BAR_HEIGHT)
}

//MARK: view creation functions
func setUpHeaderView() {
    self.navigationItem.title = "Collections"

    let negativeSpacer = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
    negativeSpacer.width = 0;

    headerSearchButton = UIBarButtonItem.init(title: "n", style: .Plain, target: self, action: #selector(CollectionsViewController.headerSearchButtonTapped))
    headerSearchButton?.width = 40
    headerSearchButton?.setTitleTextAttributes([NSFontAttributeName: Fonts.iconFont(18), NSForegroundColorAttributeName: Colors.gray()], forState: .Normal)

    self.navigationItem.rightBarButtonItems = [negativeSpacer, headerSearchButton!];
}

func createTableView() {
    collectionsTableView = UITableView(frame: CGRectZero, style: .Plain)
    collectionsTableView?.separatorStyle = .None
    collectionsTableView?.backgroundColor = Colors.white()
    collectionsTableView?.dataSource = self
    collectionsTableView?.delegate = self
    self.view.addSubview(collectionsTableView!)
}

//MARK : tableview delegate methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1;
}

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

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return CollectionsTableViewCell.getHeight()
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    if indexPath.row >= collectionArrayApiObject.collectionsArray.count {
        return UITableViewCell(frame: CGRectZero)
    }

    var tableViewCell:CollectionsTableViewCell? = tableView.dequeueReusableCellWithIdentifier("collectionsCell") as? CollectionsTableViewCell
    if (tableViewCell == nil) {
        tableViewCell = CollectionsTableViewCell(style: .Default, reuseIdentifier: "collectionsCell")
    }

    let collectionObject = collectionArrayApiObject.collectionsArray[indexPath.row]
    tableViewCell!.setCollection(collectionObject)

    return tableViewCell!
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    Commons.trackEvent(Commons.createGAcategory([Constants.COLLECTIONS_PAGE, "collection"]), action: "click", label: nil, value: 1)

    let exploreFeedForCollection = ExploreFeedViewController.init(collection: collectionArrayApiObject.collectionsArray[indexPath.row])

    //self.presentViewController(CUINavigationController.init(rootViewController: exploreFeedForCollection), animated: true, completion: nil)
    self.navigationController?.pushViewController(exploreFeedForCollection, animated: true)
}

func scrollViewDidScroll(scrollView: UIScrollView) {
    let contentOffset = scrollView.contentOffset.y
    if (collectionsTableView != nil) {
        for cell in collectionsTableView!.visibleCells {
            if (cell.isKindOfClass(CollectionsTableViewCell.self)) {
                let cellOffset = cell.y - contentOffset;

                //image parallax
                let parallaxCut: CGFloat = 0.5
                let percent = (cellOffset + cell.height)/(collectionsTableView!.height + cell.height);
                let extraHeight = cell.height * (CollectionsTableViewCell.parallaxRatio-1.0) * parallaxCut;
                let collectionCell = cell as! CollectionsTableViewCell;                    
                collectionCell.bgImageView.y = -extraHeight*percent;
            }
        }
    }

}

//MARK : get cities data functions
func getData() {
    collectionArrayApiObject = CollectionArrayApiObject()
    collectionArrayApiObject.fetchCollections(Delegate: self, CityId: self.cityId)

    if collectionArrayApiObject.collectionsArray.count == 0 {
        self.showLoader("Hmm, things are getting interesting")
    }
}

func collectionsFetchedSuccessfully() {
    self.hideNothingHereViewAndLoader()
    self.collectionsTableView?.reloadData()
    self.scrollViewDidScroll(self.collectionsTableView!)
}

func collectionsFetchingFailed(errorType: ErrorType) {
    self.showNothingHereView(errorType, icon: nil, showTryAgain: true)
}

override func didTapReloadButton() {
    self.getData()
}

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

//MARK: UIViewControllerPreviewingDelegate
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    guard let indexPath = collectionsTableView?.indexPathForRowAtPoint(location) else{
        return nil
    }

    // Lifting cell up on 3D touch before peeking
    if #available(iOS 9.0, *) {
        let cellRect = collectionsTableView?.rectForRowAtIndexPath(indexPath)
        let sourceRect = previewingContext.sourceView.convertRect(cellRect!, fromView: collectionsTableView)
        previewingContext.sourceRect = sourceRect
    }

    return ExploreFeedViewController.init(collection: collectionArrayApiObject.collectionsArray[(indexPath as NSIndexPath).row])
}

func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
    self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
}

//MARK : header button functions
func headerSearchButtonTapped() {
    let searchVC = SearchViewController(CityId: cityId)
    self.navigationController?.pushViewController(searchVC, animated: true)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

}

2 个答案:

答案 0 :(得分:0)

一些观察结果:

<强>第一

而不是使用此if语句:

if indexPath.row >= collectionArrayApiObject.collectionsArray.count {
    return UITableViewCell(frame: CGRectZero)
}

您应该使用numberOfRowsInSection来执行此操作,如下所示:

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

<强>第二

在你的cellForRowAtindexPath中,您只需要将单元格出列,然后根据需要进行设置,如下所示:

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

                //swift 3.0
                let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CollectionsTableViewCell
                //swift 2.2
                let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CollectionsTableViewCell

                let collectionObject = collectionArrayApiObject.collectionsArray[indexPath.row]
                cell.setCollection(collectionObject)
                return cell
            }

无需测试您是否使用dequeueReusableCellWithIdentifier:forIndexPath:)根据文档始终返回有效单元格

答案 1 :(得分:0)

1-如果您使用的是这样

让单元格= tableChatHome.dequeueReusableCell(withIdentifier:“ tableChatHomeCell1”,for:indexPath)为! tableChatHomeCell1

2-更改为适合我的工作

npx jetify