Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable the new Objective-C object literals on iOS?

When I create a new project with Xcode 4.4 and add these lines:

NSDictionary *test = @{ @"key" : @"test value" };
NSString *value = test[@"key"];
NSLog(@"value is: %@", value);

it compiles with no warnings and executes as expected.

Adding the same lines to an existing project produces the compiler error:

NSString *value = test[@"key"]; <-- Expected method to read dictionary element not found on object of type 'NSDictionary *'

I compared both projects' target build settings but nothing leapt out at me.

Update: The new project that successfully compiled was for OSX. I tried another new one for iOS with the above lines and it fails to compile, same as my pre-existing (iOS) project.

like image 520
darrinm Avatar asked Jul 25 '12 21:07

darrinm


1 Answers

This has nothing to do with old vs. new project, but rather is a factor of the SDK you use. The problem you're running into is that while this is a compiler feature, it requires SDK support. The iOS 5 SDK does not provide that support, though the iOS 6 SDK does.

For that reason, now you should just use the iOS 6 SDK. Read on if you want to use object subscripting with the iOS 5 SDK.

All you need to do is add a header file so that the compiler will try the call. There's no need to add an implementation; it's handled automatically by arclite. (If you are not using ARC, you will have to force the linker to include arclite. But you still don't have to actually switch to it.)

Create a new interface file, NSObject+subscripts.h.

#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
@interface NSDictionary(subscripts)
- (id)objectForKeyedSubscript:(id)key;
@end

@interface NSMutableDictionary(subscripts)
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
@end

@interface NSArray(subscripts)
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
@end

@interface NSMutableArray(subscripts)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@end
#endif

I've put this chunk on github.

Note: I used to suggest adding the required methods to NSObject before explaining how to add them only to the relevant objects. In retrospect, I believe this was an error on my part; it led to errors being caught at runtime rather than compile time, unlike the approach now presented here. That approach is still on my blog, but I now believe it to be more of a cool hack than a useful approach.

Source:

  • Peter Steinberger, Using Subscripting With Xcode 4.4 and iOS 4.3+
like image 146
Steven Fisher Avatar answered Nov 09 '22 09:11

Steven Fisher