Home > Software engineering >  Xcode 13 - Count not working on NSMutableArray anymore
Xcode 13 - Count not working on NSMutableArray anymore

Time:02-18

I have something like this in my code which worked fine for many years

NSMutableArray* DeviceList = [NSMutableArray alloc] init]; // Multi-dimensional (n x m) mutable Array filled throughout the code before arriving here:

if ([[DeviceList objectAtIndex:i] count] == 9))
        {
            [DeviceList removeObjectAtIndex:i];
        }

I haven't touched the project for a while and now upgraded to Xcode 13 and get the following error:

Multiple methods named 'count' found with mismatched result, parameter type or attributes

The error list on the left pane shows 12 options where count has been declared.

So what has changed that the simple

someNSUInteger = [[someArray] count];

creates an error and what would be a good way to fix it in 100 instances without casting every instance with (NSMutableArray*)?

Thanks a lot!

CodePudding user response:

objectAtIndex returns "id" (objects of any type). Before it used to be permissive, and you were allowed to call any method on such (such as "count").

A better way to write this code would be to declare an intermediate variable:

NSArray *deviceRow = [DeviceList objectAtIndex:i];
if ([deviceRow count] == 9) {

or if you know the type if the items inside the array, let's say you have strings:

NSArray<NSString *> *deviceRow = [DeviceList objectAtIndex:i];
if ([deviceRow count] == 9) {

and even better:

NSArray<NSString *> *deviceRow = DeviceList[i];
if (deviceRow.count == 9) {

Another problem is that there's too many instances of that, and you'd rather not touch it everywhere.

One way to fix most of the 100 occurences is to define a wrapper class for DeviceList instead of using a "naked" NSMutableArray:

@interface MyDeviceList
- (nonnull instancetype)init;
- (nullable NSArray *)objectAtIndex:(NSUInteger)index;
... any other NSMutableArray methods used in the code ...
@end

and replace the array instantiation with:

MyDeviceList *DeviceList = [MyDeviceList new];

Hopefully you have much less instantiations than unsafe usages.

You could also have some helper methods in MyDeviceList like "countAtIndex" if it happens that you need it a lot.

  • Related