2

I'm getting a crash report from Crashlytics that is always in the same place but I'm unable to replicate the crash.

It seems to be only users on iOS 9 and only very occasionally. I'm not sure if it's a code issue or something else. The last line mentions libdispatch.dylib as being missing, again, not sure if relevant.

Crashlytics indicates that the crash occurs at MMDetailTableVC.m line 1407, which is the reloadData line.

Here's what is reported:

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000001

Thread : Crashed: com.apple.main-thread
0  libobjc.A.dylib           0x20f0fae2 objc_msgSend + 1
1  CoreFoundation            0x2168b91b -[NSDictionary descriptionWithLocale:indent:] + 310
2  Foundation                0x21e77e2d _NSDescriptionWithLocaleFunc + 60
3  CoreFoundation            0x217091a3 __CFStringAppendFormatCore + 7986
4  CoreFoundation            0x21707255 _CFStringCreateWithFormatAndArgumentsAux2 + 80
5  CoreFoundation            0x2171f559 _CFLogvEx2 + 96
6  CoreFoundation            0x2171f9af _CFLogvEx3 + 118
7  Foundation                0x21f3f4f7 _NSLogv + 126
8  Foundation                0x21e8679d NSLog + 28
9  UIKit                     0x259b45fb -[UITableView reloadData] + 1818
10 Simple Meeting Minutes    0x91fff -[MMDetailTableVC saveItemEntry:] (MMDetailTableVC.m:1407)
11 Simple Meeting Minutes    0xa2edf -[MMItemViewController saveButtonAction:] (MMItemViewController.m:526)
12 UIKit                     0x25905771 -[UIApplication sendAction:to:from:forEvent:] + 80
13 UIKit                     0x25a86c71 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 140
14 UIKit                     0x25905771 -[UIApplication sendAction:to:from:forEvent:] + 80
15 UIKit                     0x25905701 -[UIControl sendAction:to:forEvent:] + 64
16 UIKit                     0x258ed61f -[UIControl _sendActionsForEvents:withEvent:] + 446
17 UIKit                     0x258ed74b -[UIControl _sendActionsForEvents:withEvent:] + 746
18 UIKit                     0x25905051 -[UIControl touchesEnded:withEvent:] + 616
19 UIKit                     0x25904cbf -[UIWindow _sendTouchesForEvent:] + 646
20 UIKit                     0x258fd5d7 -[UIWindow sendEvent:] + 642
21 UIKit                     0x258ce119 -[UIApplication sendEvent:] + 204
22 UIKit                     0x258cc757 _UIApplicationHandleEventQueue + 5134
23 CoreFoundation            0x216f9257 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
24 CoreFoundation            0x216f8e47 __CFRunLoopDoSources0 + 454
25 CoreFoundation            0x216f71af __CFRunLoopRun + 806
26 CoreFoundation            0x21649bb9 CFRunLoopRunSpecific + 516
27 CoreFoundation            0x216499ad CFRunLoopRunInMode + 108
28 GraphicsServices          0x228c3af9 GSEventRunModal + 160
29 UIKit                     0x25935fb5 UIApplicationMain + 144
30 Simple Meeting Minutes    0x8c59f main (main.m:16)
31 libdispatch.dylib         0x212fc873 (Missing)

And here's my code for saveItemEntry that always seems to be the place where the crash occurs.

- (void)saveItemEntry:(MMitem *)item{

    if (item)
    {
         NSString *resultStr = [self.meetingModel saveItem:item];

        if ([resultStr isEqualToString:@"OK"])
        {
            // all good so close form and refresh data
            [_itemViewController dismissViewControllerAnimated:NO completion:nil];

            [self.tableView reloadData];

            // or if there is an error result then display message
        }
        else if ([resultStr isEqualToString:@"DescriptionNotesMissing"])
        {
            [self showAlert:@"Missing Description or Notes" :@"An Item Description or Notes is required" :0];
            [self.itemViewController.itemDescription becomeFirstResponder];
        }
        // for any other error do nothing
    }
}
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Paul
  • 79
  • 11

2 Answers2

1

We don't know if you are calling this method in main thread or not.

And also tableview is taking time in reloading it's cell. So it would be great, if you can add these codes in dispatch_get_main_queue

dispatch_async(dispatch_get_main_queue(), ^(void){
   [_itemViewController dismissViewControllerAnimated:NO completion:nil];
   [self.tableView reloadData];
}

and

dispatch_async(dispatch_get_main_queue(), ^(void){
   [self showAlert:@"Missing Description or Notes" :@"An Item Description or Notes is required" :0];
   [self.itemViewController.itemDescription becomeFirstResponder];
}

It will be much safe, if we are working on refreshing the UI from any notification or delegation with dispatch_async(dispatch_get_main_queue(), ^(void){

Ankit Thakur
  • 4,739
  • 1
  • 19
  • 35
  • Thanks Ankit, I call the method as a delegate method from the second view controller, MMItemViewController. The first VC is a table VC containing a list of items, the second VC is used to edit an item. The user selects cancel or save to call the appropiate method in the first control. I also just noticed that I'm using [_itemViewController dismissViewControllerAnimated:No completion:nil] and elsewhere I use [self dismissViewControllerAnimated:No completion:nil] . Both work ok but the second method I believe is more correct. Do you think that could be relevant? – Paul Jan 18 '16 at 08:11
  • In using your suggested code, it wants to see a closing bracket. I put on in as follows : dispatch_async(dispatch_get_main_queue(), ^(void){ [_itemViewController dismissViewControllerAnimated:NO completion:nil]; [self.tableView reloadData]; });` is that correct? Can you explain a bit about what your code is doing? thanks – Paul Jan 18 '16 at 08:42
  • I have only shared the untested code, may be brackets are missing. – Ankit Thakur Jan 18 '16 at 09:07
  • using dispatch_Async with dispatch_get_main_queue, the UI is getting updated on GraphicService layer, which helps in updating the UI on multi-core environment. If the processor is blocked on some big UI updates in main thread, then using GCD with main_queue, we can update the other UI part in other cores. In Single Core processors, GCD is using the same core and is serialized with main_thread. – Ankit Thakur Jan 18 '16 at 09:10
  • The tableview reloadData pulls the data from sqllite3 database directly after the [self.meetingModel saveItem] method has saved the data to the database. This all occurs on the main thread, so if I understand you, under iOS 9, it maybe too busy doing this and not servicing the UI. Using the dispatch_Async with dispatch_get_main_queue ensures that the UI is updated on the main thread. Do I have that correct? – Paul Jan 18 '16 at 09:25
  • It will work like the main thread, but there is a difference in main thread and main queue. Using async process, the method will return immediatly and will perform method later. Please refer http://stackoverflow.com/questions/7905192/iphone-grand-central-dispatch-main-thread – Ankit Thakur Jan 18 '16 at 10:06
  • Thanks Ankit, I'll apply that code and see what impact it has. I won't know if it will resolve the crashes until I get the next update out and then see how many crash reports come through. Thanks again for you help. – Paul Jan 19 '16 at 18:19
  • I applied the change and published the app, unfortunately it has made the problem at lot worse rather than better. I still can't get it to crash but I've had 37 instances of the same crash reported by Fabric. Can anyone help? – Paul Feb 05 '16 at 21:52
0

Hooray - finally found the reason for this elusive problem. The crash was being due to the user being in edit mode within a UITextfield within a cell in the table when the reloadData was being called (as a result of the user tapping elsewhere or rotating the iPad, which also called ReloadData).

I fixed the issue by preceeding any [self.tableView ReloadData] with [self.view endEditing:YES] to ensure that the keyboard was dismissed and cells were not in an edit mode.

Does make sense but what a nasty trap.

dron22
  • 1,235
  • 10
  • 20
Paul
  • 79
  • 11