David T
David T

Reputation: 2764

Objective-C category for NSMutableDictionary not being respected in iOS10

I have an app written in Objective-C with a category for NSMutableDictionary. In iOS9, the app works fine. However when run in iOS10, the app crashes due to an 'unrecognized selector sent to instance'. I've isolated the problem to the NSMutableDictionary category not being respected in iOS10.

The category for NSMutableDictionary includes the following method:

- (id)getObjectForStringKeyPath:(NSString *)keysPath {
NSArray *dividedString = [keysPath componentsSeparatedByString:@"/"];
return [self getObjectForKeyPath:dividedString];
}

The line which it is crashing at is (response is type 'id'):

NSArray *textArray = [response getObjectForStringKeyPath:"someText/text"];

I've checked the response from the server and the response is valid. Also as I mentioned the crash does not happen on iOS9. It only happens on iOS10.

Does anyone know how to solve this, or any approaches to take for this problem?

Crash log

-[__NSSingleEntryDictionaryI getObjectForStringKeyPath:]: unrecognized selector sent to instance 0x608000a3f3e0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSingleEntryDictionaryI getObjectForStringKeyPath:]: unrecognized selector sent to instance 0x608000a3f3e0'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000011036034b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010fdc121e objc_exception_throw + 48
    2   CoreFoundation                      0x00000001103cff34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x00000001102e5c15 ___forwarding___ + 1013
    4   CoreFoundation                      0x00000001102e5798 _CF_forwarding_prep_0 + 120
    5   XYZApp                              0x000000010c919b7e __64-[XYZController configureConditionsTextFromHTML:]_block_invoke + 126
    6   XYZApp                              0x000000010c8e973f __41-[XYZDataProvider getTermsAndConditions:]_block_invoke + 159
    7   XYZApp                              0x000000010c8fd5ae -[XYZManager handleSuccessfulResponse:andResponseBlock:] + 110
    8   XYZApp                              0x000000010c8fbede __50-[XYZManager GET:withParameters:andResponseBlock:]_block_invoke + 126
    9   libdispatch.dylib                   0x0000000110872980 _dispatch_call_block_and_release + 12
    10  libdispatch.dylib                   0x000000011089c0cd _dispatch_client_callout + 8
    11  libdispatch.dylib                   0x000000011087ca1d _dispatch_main_queue_callback_4CF + 733
    12  CoreFoundation                      0x00000001103244f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    13  CoreFoundation                      0x00000001102e9f8d __CFRunLoopRun + 2205
    14  CoreFoundation                      0x00000001102e9494 CFRunLoopRunSpecific + 420
    15  GraphicsServices                    0x00000001131c9a6f GSEventRunModal + 161
    16  UIKit                               0x000000010e573f34 UIApplicationMain + 159
    17  XYZApp                              0x000000010c92698f main + 111
    18  libdyld.dylib                       0x00000001108e868d start + 1
    19  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Upvotes: 4

Views: 1952

Answers (2)

David T
David T

Reputation: 2764

For some undocumented reason, iOS10 believes the object type is an NSDictionary, so I created a category for NSDictionary with the getObjectForStringKeyPath method. This was the cleanest and most efficient solution for my problem.

Upvotes: 1

Phillip Mills
Phillip Mills

Reputation: 31016

The error says that the object type is __NSSingleEntryDictionaryI, not the NSMutableDictionary that you expect.

Make a mutable copy of the dictionary that the server gives you and assign that to response.

Upvotes: 4

Related Questions