8

Since the update to Xcode 5.1 I can't archive my project any more. Xcode always says "Multiple methods named "count" found with mismatched result, parameter type or attributes. This problem is new and simulator and running on device works fine. Here is the code:

    for ( int i = 0; i<[parseJSONArray count];i++){
        for (int j = 0; j<[JSON[@"data"][@"menu"][i][@"item"] count];j++){
            [pictureURL addObject:JSON[@"data"][@"menu"][i][@"item"][j][@"image"]];
        }
    }

Xcode shows the error at this point : [JSON[@"data"][@"menu"][i][@"item"] count] JSON is a NSDictionary. Whats wrong with this?

jscs
  • 63,694
  • 13
  • 151
  • 195
seniorbenelli
  • 838
  • 1
  • 9
  • 20
  • possible duplicate of [Multiple methods warning](http://stackoverflow.com/questions/5799805/multiple-methods-warning) – jscs Mar 10 '14 at 23:22

6 Answers6

17

Ask yourself: What is the type of JSON[@"data"][@"menu"][i][@"item"] ? It is "id". The compiler doesn't know which method this object responds to. You send a "count" message. The compiler goes through all the count methods of all classes that it knows about. If there are more than two different ones, it has to complain.

You could write

NSDictionary* data = JSON [@"data"];
NSArray* menu = data [@"menu"];
NSDictionary* menuI = menu [i];
NSArray* item = menuI [@"item"];

for (NSDictionary* picture in item)
    [pictureURL addObject:picture [@"image"];

More readable, easier to follow, runs faster, and easier to debug.

Of course you can also write

for (NSUInteger j = 0; j < item.count; ++j)
{
    NSDictionary* picture = item [i];
    [pictureURL addObject:picture [@"image"];
}
gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Very good point about direct iteration rather than indexing. Definitely the way to go. – jscs Mar 10 '14 at 23:26
  • Interesting. But if that's the way it works, then it will find multiple methods with same signature (same argument and return types) but which do different things. The things may not involve stuff that only the particular object in question does (which may help in identifying that this is the object this `id` is referring to), but say something generic like printing a string. Say one class's method prints **foo**, and another one prints **boo**. How will it then differentiate? – SexyBeast Oct 07 '14 at 20:17
  • It is loosing OOPS basic concept. Same method signature can be there in more than one object. – Praveen Matanam Oct 21 '14 at 10:38
2

Since there are multiple Cocoa classes with a method named count, and objectForKeyedSubscript: (to which JSON[@"data"][@"menu"][i][@"item"] resolves) returns id, the compiler can't do the typechecking it wants to do for the message send.

To stop the warning, you'll need to cast the result of JSON[@"data"][@"menu"][i][@"item"] to its actual class e.g., (NSDictionary *)(JSON[@"data"][@"menu"][i][@"item"]), or put it into a temporary variable: NSDictionary * itemDict = JSON[@"data"][@"menu"][i][@"item"];

jscs
  • 63,694
  • 13
  • 151
  • 195
1

Try:

[[[[[JSON objectForKey:@"data"] objectForKey:@"menu"] objectAtIndex: i] objectForKey:@"item"] count];

That help?

Joey Clover
  • 756
  • 5
  • 14
1

Just a cast like:

float a = [[_myArray objectForKey:@"myKey"] count] / 5.0;

float a = [(NSArray *)[_myArray objectForKey:@"myKey"] count] / 5.0;

Mário Carvalho
  • 3,106
  • 4
  • 22
  • 26
0

try with like this

for ( int i = 0; i<[(NSArray *)parseJSONArray count];i++){
    for (int j = 0; j<[JSON[@"data"][@"menu"][i][@"item"] count];j++){
        [pictureURL addObject:JSON[@"data"][@"menu"][i][@"item"][j][@"image"]];
    }
}

you need to passing

parseJSONArray

type of NSArray

masbog
  • 36
  • 4
0

In case you don't want to write code like this [((NSArray*)aId) count]:

@interface NSArray ()
- (NSUInteger) arrayElementCount;
@end

@implementation NSArray()
- (NSUInteger) arrayElementCount {
    return [self count];
}
@end

Using arrayElementCount instead of 'count'

Pingan Yi
  • 103
  • 1
  • 2