7

Is it possible to access NSArray's objects using [idx]? I have a standard library that uses [] style indexing and I don't want to rewrite the whole library to suit ObjC's objectAtIndex: method.

As in, NSArray *obj = [NSArray ...]; id item = obj[0];

AWF4vk
  • 5,810
  • 3
  • 37
  • 70

3 Answers3

20

The accepted answer (whilst true at the time) is now out of date. As of Xcode 4.5, you can now set and get NSArray elements using:

id object = array[5]; // equivalent to [array objectAtIndex:5];
mutableArray[5] = object; // equivalent to [mutableArray replaceObjectAtIndex:5 withObject:object];

You can also do the same for NSDictionaries using:

id object = dict[@"key"]; // equivalent to [dict objectForKey:@"key"];
mutableDict[@"key"] = object; // equivalent to [mutableDict setObject:object forKey:@"key"];

Even cooler, you can now create array and dictionary objects using JSON-like syntax:

NSArray *array = @[@"value1", @"value2"]; // equivalent to [NSArray arrayWithObjects:@"value1", @"value2", nil];
NSDictionary *dict = @{@"key1":@"value1", @"key2":@"value2"}; // equivalent to [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];

And in a similar vein, boxed values like NSNumber can now be written in a shorthand syntax:

NSNumber *intNumber = @5; // equivalent to [NSNumber numberWithInteger:5];
NSNumber *boolNumber = @YES; // equivalent to [NSNumber numberWithBool:YES];
NSNumber *someNumber = @(variable); // equivalent to [NSNumber numberWithWhatever:variable];

EDIT:

Far more detailed answer than mine here: What are the details of "Objective-C Literals" mentioned in the Xcode 4.4 release notes?

EDIT 2:

To be clear, though this feature wasn't added until Xcode 4.5, it works on iOS 4.3 and above, so you don't have to avoid using this if you need to support older iOS versions.

EDIT 3:

For the sake of pedantic precision, it works on Apple LLVM compiler version 4.1 and above. AKA the version that shipped with Xcode 4.5.

Community
  • 1
  • 1
Nick Lockwood
  • 40,865
  • 11
  • 112
  • 103
  • 2
    ``mutableArray[5] = object; // equivalent to [mutableArray replaceObjectAtIndex:5 withObject:object];`` is not true. It's equivalent to ``setObject:(id)anObject atIndexedSubscript:(NSUInteger)index`` – freestyler Mar 28 '13 at 07:44
  • Yes, you're right but I meant "equivalent" in the sense that it behaves the same way, not that it calls the same method. – Nick Lockwood Mar 28 '13 at 16:21
  • A little different. If mutableArray has 4 elements currently, ``mutableArray[5] = object`` is ok. But ``[mutableArray replaceObjectAtIndex:5 withObject:object]`` will raise Exception. – freestyler Mar 29 '13 at 09:39
  • Ah, interesting. I did wonder why they created new methods instead of just having the new syntax call the old ones. – Nick Lockwood Mar 29 '13 at 14:10
  • "As of Xcode 4.5" - it is not related to the version of Xcode. It's tied to the version of clang that supports this feature. –  Jun 08 '13 at 18:03
  • 1
    Sure, and it works on the version of clang that shipped with Xcode 4.5 (4.1 I think) and above. Unless you habitually install your own version of clang independently of your Xcode version, the two are equivalent. – Nick Lockwood Jun 11 '13 at 21:18
1

It is not possible, unfortunately (or not). The only option you have is to build a C++ wrapper around NSArray and override operator[]. Then, all of your files that use that wrapper should be Objective-C++ (i.e., use the .mm extension) to be correctly compiled.

EDIT:

An update to this answer. As of Xcode 4.5/iOS 6, it is possible to user subscript notation to access an NSArray elements:

 NSArray* array = ...;
 id val = array[i];

This is the official Xcode 4.5 release notes wording:

Support for subscripting using '[ ]' syntax with Objective-C container objects are supported for iOS 6.0.

(Thanks to Nick Lockwood for his comment below)

sergio
  • 68,819
  • 11
  • 102
  • 123
  • On that note, are there any open source wrappers for just this case? – AWF4vk Nov 12 '11 at 18:20
  • How do I overload any of the operators of the NSArray? Even with ObjC++ it doesn't allow me to overload those. – AWF4vk Nov 12 '11 at 20:32
  • @David: You don't. sergio's suggestion is “to build a C++ wrapper around NSArray and override `operator[]`” on that. – Peter Hosey Nov 12 '11 at 21:25
  • 1
    This information is now out of date, as of Xcode 4.5 you can access NSArray items using array[index]. – Nick Lockwood Nov 16 '12 at 19:55
  • @NickLockwood: thanks for your remark. I have edited my answer to include a reference to Xcode 4.5 release notes. – sergio Nov 16 '12 at 20:25
  • It's not limited to iOS 6. Support wasn't added to iOS until Xcode 4.5, but apps that use it will work on iOS 4.x and above if you compile using the latest SDK. – Nick Lockwood Nov 17 '12 at 10:40
0

Nope. You can, however, extract the NSArray's contents into a C array and then use the subscript operator with that.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370