1

I get the following crash:

Exception Type:  00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread:  0

Application Specific Information:
com.[app name].[app name] failed to scene-update in time

Elapsed total CPU time (seconds): 5.050 (user 5.050, system 0.000), 24% CPU 
Elapsed application CPU time (seconds): 0.044, 0% CPU

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
0   libsystem_kernel.dylib          0x0000000195018e48 semaphore_wait_trap + 8
1   libdispatch.dylib               0x0000000194efbf3c _dispatch_semaphore_wait_slow + 252
2   CFNetwork                       0x00000001832a2220 CFURLConnectionSendSynchronousRequest + 284
3   CFNetwork                       0x00000001832c27c8 +[NSURLConnection sendSynchronousRequest:returningResponse:error:] + 116
4   Foundation                      0x0000000184726358 -[NSData(NSData) initWithContentsOfURL:options:error:] + 308
5   Foundation                      0x0000000184726204 +[NSData(NSData) dataWithContentsOfURL:options:error:] + 72
6   [app name]                      0x00000001000b1a30 0x100090000 + 137776
7   [app name]                      0x00000001001e3f44 0x100090000 + 1392452
8   libdispatch.dylib               0x0000000194eed990 _dispatch_call_block_and_release + 20
9   libdispatch.dylib               0x0000000194eed950 _dispatch_client_callout + 12
10  libdispatch.dylib               0x0000000194ef2208 _dispatch_main_queue_callback_4CF + 1604
11  CoreFoundation                  0x00000001838962e8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
12  CoreFoundation                  0x0000000183894390 __CFRunLoopRun + 1488
13  CoreFoundation                  0x00000001837c11f0 CFRunLoopRunSpecific + 392
14  GraphicsServices                0x000000018cae36f8 GSEventRunModal + 164
15  UIKit                           0x0000000188152108 UIApplicationMain + 1484
16  [app name]                      0x00000001000dd2ac 0x100090000 + 316076
17  libdyld.dylib                   0x0000000194f1aa04 start + 0

On the following code:

    @try {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
            NSData* data = [NSData dataWithContentsOfURL:xxxxxxx options:NSDataReadingUncached error:&error];
           ...
          [self.buffer performSelectorOnMainThread:@selector(addObject:) withObject:data waitUntilDone:YES];
   }
    @catch (NSException* error) {
        NSLog(@"error: %@", error);
    }

Yes there is a failure block too, but I simplified the code to the essence, the pure code that causes the crash.

This code runs hundreds of times per hour without any problem. But every now and then it crashes. Always the same crash (like the one above). First, the app freezes, then it crashes. The catch-block is never executed.

The performSelectorOnMainThread uses an object. And that object is added (in the main thread) to an NSMutableArray (self.buffer is an NSMutableArray). I know that NSMutableArrays are not thread-safe and that's why I perform them on the main thread. For waitUntilDone I use YES to prevent the thread from ending before the object is inserted. I used NO too, but that crashes constantly.

Does anyone have an idea why this crash happens? And do you perhaps have a solution for me to prevent this?

Thanks a lot.

ystack
  • 1,785
  • 12
  • 23
  • what happens if you set waitUntilDone:NO ? – Erik Johansson Apr 04 '15 at 08:58
  • 1
    Like I said above: "I used NO, but that crashes constantly". Besides, it would be a bit shameful to ask the question without having tried that first. –  Apr 04 '15 at 09:09
  • In the code snippet, is there a `});` missing for closing the block and finishing the call statement `of dispatch_async()`? – Daniel S. Apr 04 '15 at 10:33
  • 1
    Yes, I know. It is not complete. It is just to give an idea of how the code is made. If my project would miss the `});` too than I would not be able to build and run it at all. So that is not the reason of the crash. Thanks. –  Apr 04 '15 at 10:56
  • Hey, i'm having the same problem, did you solve it yet? – ssj Apr 25 '15 at 23:57

2 Answers2

0

You are doing network i/o on the main thread while updating the UI. This takes too long. Don't do that on the main thread. Instead, use an asynchronous way to run the URL fetch and cache the result so it can be used by the next user interface update.

More information:

https://developer.apple.com/library/ios/qa/qa1693/_index.html

Daniel S.
  • 6,458
  • 4
  • 35
  • 78
  • I don't do that. I do `dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {` which means the networking stuff is not done on the main thread. Only adding the object `[NSMutableArrayInstance addObject:io]` is done on the main thread. That should be ok, I guess. –  Apr 04 '15 at 09:23
0

Writing to the array on the main thread does not make it thread safe. Use a dedicated dispatch_queue to control access to the nsmutablearray instead, both read and write operations.

https://stackoverflow.com/a/4607664/573988

Community
  • 1
  • 1
Erik Johansson
  • 1,188
  • 1
  • 8
  • 22