Xcode 4.4 adds support for Obj-C literals
itunes.apple.com
itunes.apple.com
NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42]
NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535]
NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES]
NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];
NSDictionary *dictionary = @{
@"name" : NSUserName(),
@"date" : [NSDate date],
@"processInfo" : [NSProcessInfo processInfo]
};
This, especially the NSArray/NSDictionary stuff, should make coding in Obj-C so much faster and more pleasant - well done LLVM team!PS: Not sure if the object subscripting stuff is supported yet, but that looks awesome too!
For NSArray:
- (id)objectAtIndexedSubscript:(NSUInteger)index {
return [self objectAtIndex:index];
}
NSMutableArray: - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index {
if (index < self.count){
if (object)
[self replaceObjectAtIndex:index withObject:object];
else
[self removeObjectAtIndex:index];
} else {
[self addObject:object];
}
}
NSDictionary: - (id)objectForKeyedSubscript:(id)key {
return [self objectForKey:key];
}
NSMutableDictionary: - (void)setObject:(id)object forKeyedSubscript:(id)key {
[self setObject:object forKey:key];
} -(id)objectAtIndexedSubscript:(NSUInteger)index;
-(void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
as weiran has shown for NS(Mutable)Array/NS(Mutable)Dictionary.This isn't my code, but I've been happily using it for a week or so now: https://gist.github.com/3299750
int foo = 42;
NSNumber* boxed = @foo; // fails
NSNumber* boxed = @(foo); // works
One thing that isn't supported but would be extremely useful is a shortcut for NSValue boxing. Fortunately, it's really easy to solve using a short macro, e.g.: #define BOXED(val) ({ typeof(val) _tmp_val = (val); [NSValue valueWithBytes:&(_tmp_val) objCType:@encode(typeof(val))]; })
CGRect rect = {{ 0, 0 }, {100,200}};
NSValue* boxed = BOXED(rect); int x = some_nsvalue; // it knows you want an int
[obj takeDouble:some_nsvalue]; // it knows takeDouble expects a double
(CGAffineTransform)some_nsvalue // typecast is the ultimate hint SSDC_BIND_DICTIONARY_TYPED(result,
NSArray, errors, @"errors",
NSArray, warnings, @"warnings",
NSNumber, new_volume, @"volume-new",
NSString, volume_name, @"volume-name",
NSString, volume_type, @"volume-type",
NSDictionary, fs_size, @"filesystem-size",
NSDictionary, host, @"host",
NSDictionary, cache, @"cache",
NSArray, unmount_required, @"unmount-required",
NSArray, unmount_recommended, @"unmount-recommended");
This expands into variable declarations and type-checked initialisations from objectForKey: method calls which otherwise are very messy. You could define something similar for extracting and binding from NSValues in one step, though none of this is very elegant.That being said, that doesn't have much to do with what I'm talking about because here I'm referring specifically to NSValue -> primitive type conversion. Just about every compiler is super picky about this. Try doing this in Xcode:
void * p;
int x = p;
It will get angry, it knows p is a pointer and you want an int. Couple this with Xcode also knowing whether something is just id or actually an NSValue, and you can then do this: id something = [object returnIdSoYouDontWhatItReallyIs];
int somethingAsInt = something; // error, something can't be converted to int
However, here it should be fine: NSValue * something = [object returnsSomethingMysterious];
int somethingAsInt = something; // OK, replace with something.intValue
Of course, you'd probably want some sort of explicit unboxing operator (to match the explicit boxing operator @()), because sometimes you do want to do crazy things like cast a id to an int. Maybe something like: @^()