com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS in cellForRowAt

3.8k Views Asked by At

I have experienced this crash in cellForRowAt the line number Crashlytics pointed me to was:

cell.table = questionTable

the entire case around that line is:

case .mcq_single:
if let cell = tableView.dequeueReusableCell(withIdentifier: "IQ_MCQCell") as? IQ_MCQCell
{
       cell.table = questionTable;
       cell.delegate = self;
       cell.qID = answerIDs![indexPath.row];
       cell.selectionStyle = .none

       if questionNA[indexPath.row]
       {
           cell.NABox.setImage(#imageLiteral(resourceName: "checkbox_selected"), for: .normal);
           cell.questionItem.isHidden = true;
       } else {
           cell.NABox.setImage(#imageLiteral(resourceName: "checkbox_up"), for: .normal);
           cell.questionItem.isHidden = false;
       }

       let cell2 = cell.formatCell(with: item, for: cell, at: indexPath)
       textHeight[indexPath.row] = cell.questionText.numberOfVisibleLines
       return cell2;
}


Crashed: com.apple.main-thread
0  libswiftCore.dylib             0x10281a7e8 swift_unknownRetain + 8
1  AppName                        0x100f24b48 specialized InspectionItemVC.tableView(UITableView, cellForRowAt : IndexPath) -> UITableViewCell (InspectionItemVC.swift:887)
2  FlexConnect                    0x100f1f2b8 @objc InspectionItemVC.tableView(UITableView, cellForRowAt : IndexPath) -> UITableViewCell (InspectionItemVC.swift)
3  UIKit                          0x18f537ac4 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:]
4  UIKit                          0x18f538028 -[UITableView _createPreparedCellForGlobalRow:willDisplay:]
5  UIKit                          0x18f5168ac -[UITableView _updateVisibleCellsNow:isRecursive:]
6  UIKit                          0x18f2cd33c -[UITableView layoutSubviews]
7  UIKit                          0x18f1f9f00 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
8  QuartzCore                     0x189c89998 -[CALayer layoutSublayers]
9  QuartzCore                     0x189c8db20 CA::Layer::layout_if_needed(CA::Transaction*)
10 UIKit                          0x18f20eccc -[UIView(Hierarchy) layoutBelowIfNeeded]
11 UIKit                          0x18f2a46f4 -[UINavigationController _layoutViewController:]
12 UIKit                          0x18f2a1dc4 -[UINavigationController _layoutTopViewController]
13 UIKit                          0x18f2bac64 -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
14 UIKit                          0x18f2ba908 -[UINavigationTransitionView _notifyDelegateTransitionDidStopWithContext:]
15 UIKit                          0x18f2ba4e0 -[UINavigationTransitionView _cleanupTransition]
16 UIKit                          0x18f234bb4 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
17 UIKit                          0x18f232cb8 +[UIViewAnimationState popAnimationState]
18 UIKit                          0x18f2adc48 -[UINavigationTransitionView transition:fromView:toView:]
19 UIKit                          0x18f2a3d24 -[UINavigationController _startTransition:fromViewController:toViewController:]
20 UIKit                          0x18f2a2e14 -[UINavigationController _startDeferredTransitionIfNeeded:]
21 UIKit                          0x18f2a2890 -[UINavigationController __viewWillLayoutSubviews]
22 UIKit                          0x18f2a2790 -[UILayoutContainerView layoutSubviews]
23 UIKit                          0x18f1f9f00 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
24 QuartzCore                     0x189c89998 -[CALayer layoutSublayers]
25 QuartzCore                     0x189c8db20 CA::Layer::layout_if_needed(CA::Transaction*)
26 QuartzCore                     0x189bfa36c CA::Context::commit_transaction(CA::Transaction*)
27 QuartzCore                     0x189c21b90 CA::Transaction::commit()
28 UIKit                          0x18f1ef5c8 _afterCACommitHandler
29 CoreFoundation                 0x185bededc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
30 CoreFoundation                 0x185beb894 __CFRunLoopDoObservers
31 CoreFoundation                 0x185bebe50 __CFRunLoopRun
32 CoreFoundation                 0x185b0be58 CFRunLoopRunSpecific
33 GraphicsServices               0x1879b8f84 GSEventRunModal
34 UIKit                          0x18f26067c UIApplicationMain
35 AppName                        0x100094590 main (AppDelegate.swift:23)
36 libdyld.dylib                  0x18562856c start

Update:

weak var delegate: inspQDelegate? 
// weak added here
var indexPath: IndexPath?
//var table   : UITableView?; table removed indexPath used instead.

inspQDelegate is defined like so:

public protocol inspQDelegate
{
    func setNA(at index: IndexPath);
    func setAnswer(at index: IndexPath, value: String);
    func setComment(at index: IndexPath, value: String);
    func scrollToMe(at index: IndexPath)
}

Update 2: When inspQdelegate was defined like so:

public protocol inspQDelegate: NSObjectProtocol
{
    func setNA(at index: IndexPath);
    func setAnswer(at index: IndexPath, value: String);
    func setComment(at index: IndexPath, value: String);
    func scrollToMe(at index: IndexPath)
}

I received a new crash on line cell.delegate = self below:

case .true_false:
     if let cell = tableView.dequeueReusableCell(withIdentifier: "IQ_FlipCell") as? IQ_FlipCell {
            cell.table = questionTable;
            cell.delegate = self;
            cell.qID = answerIDs![indexPath.row];
            cell.selectionStyle = .none

            if questionNA[indexPath.row]
            {
                cell.NABox.setImage(#imageLiteral(resourceName: "checkbox_selected"), for: .normal);
                cell.questionItem.isHidden = true;
            } else {
                cell.NABox.setImage(#imageLiteral(resourceName: "checkbox_up"), for: .normal);
                cell.questionItem.isHidden = false;
            }

            let cell2 = cell.formatCell(with: item, for: cell, at: indexPath, qtype: 0)
            textHeight[indexPath.row] = cell.questionText.numberOfVisibleLines
            return cell2;
     }

But when defined like:

public protocol inspQDelegate: class
{...}

I did not receive this new crash

1

There are 1 best solutions below

14
On BEST ANSWER

It looks like you are creating a retain cycle between your tableView and it's cells. Cells are dequeued and reused often, so you shouldn't be using strong references. Your cell has a delegate which is set to the tableView anyway, so you shouldn't need to set cell.tableView, just use the delegate.

When declaring your delegate and tableView in the cell. (I would advise NOT to have the tableView property) make sure that you use a weak reference and this should solve your issue.

weak var delegate: MyTableViewDelegateProtoocol?
weak var tableView: UITableView?

Give it a try and let me know the outcome

Here is an article that helps explain retain cycles and memory management in Swift

UPDATE:

public protocol inspQDelegate: class
{
    func setNA(at index: IndexPath);
    func setAnswer(at index: IndexPath, value: String);
    func setComment(at index: IndexPath, value: String);
    func scrollToMe(at index: IndexPath)
}