heightForRowAtIndexPath间歇性崩溃

时间:2015-12-15 09:20:39

标签: ios swift uitableview cgfloat heightforrowatindexpath

我有一个拥有约30名活跃用户和500多名注册用户的应用,这个问题只发生在9.2使用iPhone 6的人身上。

我可以从崩溃报告中看到她有超过60次崩溃,她说有时候问题还行,而不是其他问题。

我在这里有相同的测试设备,没有问题发生。

我无法从结构中获取大量崩溃报告的详细信息,但崩溃发生在以下方法中且应用程序崩溃在此方法的最终其他,我可以从她对问题的描述:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        let bounds = UIScreen.mainScreen().bounds
        var screenWidth = bounds.size.width
        let screenHeight = bounds.size.height
        if indexPath.row == 0 {
            let font = UIFont(name: "Helvetica Neue", size: 17.0)
            let heightCalc = heightForView(self.postDescription!, font: font!, width: screenWidth - 32)
            if self.photoWidth != nil{

                let imageAspectRatio = self.photoWidth!/self.photoHeight!
                var imageViewFrameHeight = screenWidth/imageAspectRatio
                if self.portBool {
                    if imageViewFrameHeight > (screenHeight - 64) {
                        screenWidth = screenWidth * 0.60
                        imageViewFrameHeight = imageViewFrameHeight * 0.60
                    }
                }

                return imageViewFrameHeight + 136 + heightCalc + 26
                //return 557
            }
            else{
                return 136 + heightCalc + 30
            }
        }
        else if indexPath.row == 1 {
            return 50.0
        }
        else if indexPath.row == 2{
            return 40.0
        }
        else{

            if self.commentsDetailed != nil && self.commentsDetailed!.count >= (indexPath.row - 3)
            {
                let commentsDetailed = self.commentsDetailed![indexPath.row-3]
                let font = UIFont(name: "Helvetica Neue", size: 14.0)

                let heightCalc = heightForView(commentsDetailed.comment!, font: font!, width: screenWidth - 51)

                if commentsDetailed.authorId == Prefs.userId.description {
                    return 45 + heightCalc + 40 + 30
                    //return 131.5
                }
                else{
                    return 45 + heightCalc + 40
                    //return 101.5
                }

            }
            else {
                return 80.0
            }

        }
    }

对于那些想知道的人,我需要计算高度以避免在我使用表格视图自动尺寸时发生的抖动滚动。所以我只需要在这里解决问题而不是切换方法。

来自crashlytics的一些信息:

EXC_BREAKPOINT

Thread : Crashed: Thread
0  ProjectName                   0x10008a64c specialized NewFeedDetailedController.tableView(UITableView, heightForRowAtIndexPath : NSIndexPath) -> CGFloat (NewFeedDetailedController.swift)
1  ProjectName                   0x100085258 @objc NewFeedDetailedController.tableView(UITableView, heightForRowAtIndexPath : NSIndexPath) -> CGFloat (NewFeedDetailedController.swift)
2  UIKit                          0x187683638 __66-[UISectionRowData refreshWithSection:tableView:tableViewRowData:]_block_invoke + 396
3  UIKit                          0x187641818 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 3948
4  UIKit                          0x1876407d4 -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 412
5  UIKit                          0x187640590 -[UITableViewRowData heightForTable] + 64
6  UIKit                          0x18764039c -[UITableView _updateContentSize] + 220
7  UIKit                          0x1878a6f60 -[UITableView _rebuildGeometry] + 44
8  UIKit                          0x1876462c8 -[UITableView didMoveToWindow] + 144
9  UIKit                          0x18755705c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1496
10 UIKit                          0x18757c568 -[UIScrollView _didMoveFromWindow:toWindow:] + 92
11 UIKit                          0x187556d7c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
12 UIKit                          0x187556310 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 152
13 Foundation                     0x183189500 -[NSISEngine withBehaviors:performModifications:] + 168
14 UIKit                          0x187556194 -[UIView(Hierarchy) _postMovedFromSuperview:] + 532
15 UIKit                          0x187563b80 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1784
16 UIKit                          0x187755600 -[_UIParallaxDimmingView didMoveToWindow] + 180
17 UIKit                          0x18755705c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1496
18 UIKit                          0x187556d7c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
19 UIKit                          0x187556310 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 152
20 Foundation                     0x183189500 -[NSISEngine withBehaviors:performModifications:] + 168
21 UIKit                          0x187556194 -[UIView(Hierarchy) _postMovedFromSuperview:] + 532
22 UIKit                          0x187563b80 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1784
23 UIKit                          0x1877f5db4 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke_2 + 1656
24 UIKit                          0x18756a964 +[UIView(Animation) performWithoutAnimation:] + 80
25 UIKit                          0x187755118 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke + 260
26 UIKit                          0x187870840 +[UIView(Internal) _performBlockDelayingTriggeringResponderEvents:] + 220
27 UIKit                          0x187754c90 -[_UINavigationParallaxTransition animateTransition:] + 1060
28 UIKit                          0x18770e6a0 -[UINavigationController _startCustomTransition:] + 3544
29 UIKit                          0x18761a9b8 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
30 UIKit                          0x18761a694 -[UINavigationController __viewWillLayoutSubviews] + 60
31 UIKit                          0x18761a5fc -[UILayoutContainerView layoutSubviews] + 208
32 UIKit                          0x187557778 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 656
33 QuartzCore                     0x184f66b2c -[CALayer layoutSublayers] + 148
34 QuartzCore                     0x184f61738 CA::Layer::layout_if_needed(CA::Transaction*) + 292
35 QuartzCore                     0x184f615f8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
36 QuartzCore                     0x184f60c94 CA::Context::commit_transaction(CA::Transaction*) + 252
37 QuartzCore                     0x184f609dc CA::Transaction::commit() + 512
38 UIKit                          0x18754dc78 _afterCACommitHandler + 180
39 CoreFoundation                 0x182820588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
40 CoreFoundation                 0x18281e32c __CFRunLoopDoObservers + 372
41 CoreFoundation                 0x18281e75c __CFRunLoopRun + 928
42 CoreFoundation                 0x18274d680 CFRunLoopRunSpecific + 384
43 GraphicsServices               0x183c5c088 GSEventRunModal + 180
44 UIKit                          0x1875c4d90 UIApplicationMain + 204
45 ProjectName                   0x1001663b0 main (AppDelegate.swift:21)
46 libdyld.dylib                  0x1822ee8b8 start + 4 

还有heightForView功能:

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
        let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.ByWordWrapping
        label.font = font
        label.text = text

        label.sizeToFit()
        return label.frame.height
    }

更新了代码并检查了nil,但用户仍在崩溃:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        let bounds = UIScreen.mainScreen().bounds
        var screenWidth = bounds.size.width
        let screenHeight = bounds.size.height
        if indexPath.row == 0 {
            CLSLogv("crashing in indexPath.Row = 0 %@", getVaList(["returning 50.0 here"]))

            let font = UIFont(name: "Helvetica Neue", size: 17.0)

            if let description = self.postDescription {
                let heightCalc = heightForView(description, font: font!, width: screenWidth - 32)
                if self.photoWidth != nil && self.photoHeight != nil {
                    CLSLogv("crashing in indexPath.Row = 0 %@", getVaList(["inside photowidth is not nil"]))
                    let imageAspectRatio = self.photoWidth!/self.photoHeight!
                    var imageViewFrameHeight = screenWidth/imageAspectRatio
                    if self.portBool {
                        if imageViewFrameHeight > (screenHeight - 64) {
                            screenWidth = screenWidth * 0.60
                            imageViewFrameHeight = imageViewFrameHeight * 0.60
                        }
                    }

                    return imageViewFrameHeight + 136.0 + heightCalc + 26.0
                    //return 557
                }
                else{
                    CLSLogv("crashing in indexPath.Row = 0 %@", getVaList(["when photowidth is nil"]))
                    return 136.0 + heightCalc + 30.0
                }
            }
            else{
                CLSLogv("crashing in indexPath.Row = 0 %@", getVaList(["unable to unwrap self.postDescription"]))
                if self.photoWidth != nil && self.photoHeight != nil {
                    let imageAspectRatio = self.photoWidth!/self.photoHeight!
                    var imageViewFrameHeight = screenWidth/imageAspectRatio
                    if self.portBool {
                        if imageViewFrameHeight > (screenHeight - 64) {
                            screenWidth = screenWidth * 0.60
                            imageViewFrameHeight = imageViewFrameHeight * 0.60
                        }
                    }

                    return imageViewFrameHeight + 136.0 + 26.0
                }
                else{
                    return 136.0 + 30.0
                }
            }
        }
        else if indexPath.row == 1 {
             CLSLogv("crashing in indexPath.Row = 1 %@", getVaList(["returning 50.0 here"]))
            return 50.0
        }
        else if indexPath.row == 2 {
            CLSLogv("crashing in indexPath.Row = 2 %@", getVaList(["returning 40.0 here"]))
            return 40.0
        }
        else{

            if self.commentsDetailed != nil && self.commentsDetailed!.count > (indexPath.row - 3)
            {

                if let commentsDetailed = self.commentsDetailed?[indexPath.row-3]{


                    let font = UIFont(name: "Helvetica Neue", size: 14.0)
                    if let comment = commentsDetailed.comment{
                        let heightCalc = heightForView(comment, font: font!, width: screenWidth - 51)
                        if commentsDetailed.authorId == Prefs.userId.description {
                            return 45.0 + heightCalc + 40.0 + 30.0
                        }
                        else{
                            return 45.0 + heightCalc + 40.0
                        }
                    }
                    else{
                        if commentsDetailed.authorId == Prefs.userId.description {
                            return 45.0 + 40.0 + 30.0
                        }
                        else{
                            return 45.0 + 40.0
                        }
                    }
                }
                else {
                     CLSLogv("in the else for defining commentsDetailed %a",getVaList(["commentsdetailed"]))
                    return 80.0
                }
            }
            else {
                CLSLogv("in the condition for checking commentsDetailed = nil - true %a", getVaList(["CRASH RELATED TO RETURNING 80 IF ARRAY IS NIL?"]))
                return 80.0
            }

        }
    }

3 个答案:

答案 0 :(得分:1)

我认为第二个其他可能失败的唯一可能点是commentsDetailed.comment!展开,如果它等于nil则会失败。其余的看起来非常强大,包括heightForView方法。如果检查commentsDetailed.comment != nil没有做到这一点,我会开始认为它是一些随机的9.2早期错误...

答案 1 :(得分:1)

错误是在最后一次关闭时弹出的数组,就像你说的那样:

if self.commentsDetailed != nil && self.commentsDetailed!.count >= (indexPath.row - 3)
     {
        let commentsDetailed = self.commentsDetailed![indexPath.row-3]

例如,如果数组的大小为1,那么您可以索引的最后一个元素是arr [0]但是count> =(indexPath.row - 3)将使索引arr [1]导致错误。

由于重复调用此方法,因此还可以执行其他修改以进行优化。 (我建议可能在外面使用字体和其他变量,这样它每次都不会创建它们。可能有这样的优化,但我不确定)。

我不得不重新编写整个游乐场才能找到问题所以我想我只是在这里粘贴代码:)

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: 
    NSIndexPath) -> CGFloat {
    var screenWidth = UIScreen.mainScreen().bounds.size.width
    let screenHeight = UIScreen.mainScreen().bounds.size.height

    switch indexPath.row {

    case 0:

        guard let font = UIFont(name: "Helvetica Neue", size: 17.0) else { 
            print("Font not Found !")
            break
        }
        let heightCalc = heightForView(self.postDescription! ?? "", font: font, width: screenWidth - 32)

        guard let photoWidth = self.photoWidth, let photoHeight = self.photoHeight else {
            return 136 + heightCalc + 30
        }
        let imageAspectRatio = photoWidth / photoHeight
        var imageViewFrameHeight = screenWidth / imageAspectRatio
        if self.portBool {
            if imageViewFrameHeight > (screenHeight - 64) {
                screenWidth = screenWidth * 0.60
                imageViewFrameHeight = imageViewFrameHeight * 0.60
            }
        }
        return imageViewFrameHeight + 136 + heightCalc + 26
        //return 557

    case 1: return 50.0
    case 2: return 40.0

    case _ where self.commentsDetailed != nil && indexPath.row >= 3: 

        let index = indexPath.row - 3
        //I think your problem was here (your index can not be equal to the count!)
        guard let detailed = self.commentsDetailed where detailed.count > index
            else { break }

        let commentsDetailed = detailed[index]
        guard let font = UIFont(name: "Helvetica Neue", size: 14.0) else { 
            break //font not found
        }

        let heightCalc = heightForView(commentsDetailed.comment! ?? "", font: font, width: screenWidth - 51)

        if commentsDetailed.authorId == Prefs.userId.description { //make sure author id is always string. sounds like a number
            return 45 + heightCalc + 40 + 30
            //return 131.5
        }
        else{
            return 45 + heightCalc + 40
            //return 101.5
        }

    default: return 80.0
    }
}

答案 2 :(得分:0)

您的代码中仍然存在一些不一致之处。尝试区分代码中的self.comentsDetailedcomentsDetailed。尝试为示例选择本地值let cd = self.commentsDetailed![indexPath.row-3]的另一个名称,然后在下一个语句中使用此值。这可以帮助您查看代码中发生的错误。