1

Recently I have upgraded XCode8 I am facing issue in isKindOfClass method this code is working till to iOS9 but in iOS10 suddenly [items isKindOfClass: [NSMutableArray class]] compiler not going in for loop condition may I know what is the reason?

NSMutableArray is child class of NSArray so when I am changing to [NSArray class] then it works fine so I am confuse why this change affect to NSMutableArray class which is child class of NSArray ?

     NSMutableArray *items = [jsonDictionary objectForKey:@"items"]; // Here i am taking response in NSMutableArray

     if ([items isKindOfClass: [NSMutableArray class]] && items != nil) // not working  {
         for (NSMutableDictionary *item in items)
         {
           // Rest of Code
         }
     }

This code works for me I m confuse the above code working until iOS9 when I change this below code then after working in iOS10:

     NSMutableArray *items = [jsonDictionary objectForKey:@"items"];

     if ([items isKindOfClass: [NSArray class]] && items != nil) // Changed to NSArray  {
         for (NSMutableDictionary *item in items)
         {
           // Rest of Code
         }
     }
Mayank Patel
  • 3,868
  • 10
  • 36
  • 59
  • How are you parsing the JSON? Are you setting the option for mutable containers? Have you set a breakpoint and checked with a debugger, what `items` actually is? All the evidence points to it being an `NSArray` rather than an `NSMutableArray` – Paulw11 Sep 16 '16 at 04:20
  • @Paulw11 Yesi have checked all the things i have checked with debuger items has a items and this 1st block of code working till to iOS9 and i have checked with debugger when i changed NSMutableArray to NSArray then it will working fine and this happened only in iOS10 – Mayank Patel Sep 16 '16 at 04:22
  • So, what is the class of `items` shown in the debugger? – Paulw11 Sep 16 '16 at 04:23
  • it will showing `NSArray` class but NSMutableArray is child class of NSArray then why that is not working – Mayank Patel Sep 16 '16 at 04:24
  • So, there is your answer. It is an NSArray. The problem isn't with `isKindOfClass` it is with how you are creating your objects. There is an option you can pass to `NSJSONSerializer` if you want mutable containers. By default you get immutable containers. – Paulw11 Sep 16 '16 at 04:25
  • may i know why it is working in iOS9 ? – Mayank Patel Sep 16 '16 at 04:26
  • `isKindOfClass` will match superclasses, but not subclasses. So if x is an `NSMutableArray` then both `[x isKindOfClass: [NSArray class]]` and `[x isKindOfClass: [NSMutableArray class]]` will return true. But if x is an `NSArray` then only the first will be true, since a superclass instance isn't a subclass. – Paulw11 Sep 16 '16 at 04:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123494/discussion-between-paulw11-and-mayank-patel). – Paulw11 Sep 16 '16 at 04:27

1 Answers1

2

From your comments, it seems that you actually have an NSArray, not an NSMutableArray, so isKindOfClass is working correctly. AFN will give immutable containers unless you specify otherwise, and this shouldn't be any different on iOS 10, so I am not sure why it was working previously.

Rather than testing for a mutable array, it is probably simpler to create a mutable copy of whatever is there, this way you don't have to try and handle the "failure" condition gracefully:

NSArray *items = [jsonDictionary objectForKey:@"items"];
if (items != nil) {
     NSMutableArray *mutableItems = [items mutableCopy];
     for (NSMutableDictionary *item in mutableItems)
     {
       // Rest of Code
     }
 }

Beware, unless you have specified the option to AFN to provide mutable containers, the dictionaries inside your items array will be NSDictionary not NSMutableDictionary, so you may need to make mutable copies of them.

Of course, if you aren't mutating the array or the dictionary, then you can just u NSArray and NSDictionary regardless of whether you have a mutable or immutable object.

Paulw11
  • 108,386
  • 14
  • 159
  • 186