- [NSUserDefault setObject:forKey:] cause random crash only on iOS 11.

In our app, we got the following crashes that occurs only on iOS 11. In iOS 11, whether there was a system bug that
cause the following crash? Our app support iOS 9 and later.

Code Block
Fatal Exception: NSRangeException
*** -[NSArray initWithArray:range:copyItems:]: range {0, 2} extends beyond bounds [0 .. 0]
0 CoreFoundation 0x184622d8c exceptionPreprocess
1 libobjc.A.dylib 0x1837dc5ec objc_exception_throw
2 CoreFoundation 0x1845bb750 _CFArgv
3 CoreFoundation 0x1844ef5a0 -[NSArray initWithArray:range:copyItems:]
4 UIKit 0x18e1b3a20 +[_UICanvas canvases]
5 UIKit 0x18e1b3958 +[_UIApplicationCanvas canvases]
6 UIKit 0x18e1b38bc +[_UIApplicationCanvas mostActiveCanvas]
7 UIKit 0x18e1b386c -[UIApplication isSuspended]
8 UIKit 0x18e4f4824 UpdateSystemSoundActiveStatus
9 UIKit 0x18e4f492c IsSystemSoundEnabled
10 UIKit 0x18e4f4760 UpdateSystemSoundActiveStatus
11 UIKit 0x18e3c57cc -[UIDevice _updateSystemSoundActiveStatus:]
12 CoreFoundation 0x1845b4c3c CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER
13 CoreFoundation 0x1845b41b8 _CFXRegistrationPost
14 CoreFoundation 0x1845b3f14 _CFXNotificationPost_block_invoke
15 CoreFoundation 0x18463184c -[_CFXNotificationRegistrar find:object:observer:enumerator:]
16 CoreFoundation 0x1844eaf38 _CFXNotificationPost
17 Foundation 0x184f5bbbc -[NSNotificationCenter postNotificationName:object:userInfo:]
18 XX 0x1060748b4 +[UMConfigureCache setObject:forKey:]
19 XX 0x10608439c +[UMBuildPayload updateImprint:]
20 XX 0x106084d90 -[UMBuildPayload verifyResponseData:]
21 XX 0x106071c68 -[UMNetworkWork postDataToServer:withFile:]
22 XX 0x10607175c -[UMNetworkWork postDataWithFile:]
23 XX 0x10607128c -[UMNetworkWork main]
24 Foundation 0x184f8bcac -[NSOperationInternal _start:]
25 Foundation 0x18504c76c NSOQSchedule_f
26 libdispatch.dylib 0x183f14ae4 _dispatch_client_callout
27 libdispatch.dylib 0x183f1cf18 _dispatch_continuation_pop$VARIANT$mp
28 libdispatch.dylib 0x183f1b850 _dispatch_async_redirect_invoke$VARIANT$mp
29 libdispatch.dylib 0x183f21d30 _dispatch_root_queue_drain
30 libdispatch.dylib 0x183f21a80 _dispatch_worker_thread3
31 libsystem_pthread.dylib 0x184247fac _pthread_wqthread
32 libsystem_pthread.dylib 0x184247b08 start_wqthread


Also, I discover other crash like these:
  1. Crash [__NSArrayM getObjects:range:]: range {0, 3} extends beyond bounds [0 .. 1]

  2. ADBMobile.collectLifecycleData() crash randomly in application didFinishLaunchingWithOptions

  3. [iOS SDK] UIKit non-main thread crash


I’m confused by your post. Your title mentions NSUserDefaults but there’s reference to user defaults in the exception backtrace. How is user defaults involved here?

Also, can you post an example crash report?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
We used a third-party SDK in our application.
The method +[UMConfigureCache setObject:forKey:] from that third-party SDK.
The logic of the method +[UMConfigureCache setObject:forKey:] looks like the following:

Code Block objective_c
if ((value != nil) && [UMUtils notEmptyString:key]) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:value forKey:key];
[defaults synchronize];
}

Thanks for clarifying. Now that I know what to look for, I can see this code in frame 18 of your backtrace.

What’s happening here is that your code has set a user defaults vualue which has triggered a notification. In frame 12 the notification centre is calling out to someone who’s observing that notification. That’s triggered a long sequence of calls that’s crashed your app.

Looking at the base of your stack it seems to be running on a secondary thread. Specifically, frames 32 through 26 are typically of Dispatch calling a block from one of its worker threads. However, frames 11 through 4 are in UIKit, which is generally not callable from a secondary thread. It’s possible that UIKit is expecting this notification to always come in on the main thread and your code is breaking its (erroneous) assumption.

Can you reproduce this internally? If so, try bouncing to the main thread before setting that user default.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
- [NSUserDefault setObject:forKey:] cause random crash only on iOS 11.
 
 
Q