4 ms·
See http://clang.llvm.org/docs/ObjectiveCLiterals.html http://clang.llvm.org/docs/ObjectiveCLiterals.html for more information, but some examples from that page
by BenjieGillam 14y ago
See http://clang.llvm.org/docs/ObjectiveCLiterals.html http://clang.llvm.org/docs/ObjectiveCLiterals.html for more information, but some examples from that page:
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!
- upinsmoke 14y agoSubscripting only on OS X not iOS.
- weiran 14y agoYou can use them on iOS 5.1 by implementing the methods the subscripts map to on NSArray and NSDictionary (as well as mutable) in categories. 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]; }
- michaelmior 14y agoIs it just as easy as creating categories that add these methods?
- puls 14y agoThe implementation already exists in iOS 5, you just need to make the compiler happy; a header that declares them is sufficient.
- BenjieGillam 14y agoApparently OSX 10.8 and iOS 6 bring support for subscripting to native NSArray/NSDictionary, but I think you can add subscripts to your own classes already just by implementing the following methods: -(id)objectAtIndexedSubscript:(NSUInteger)index; -(void)setObject:(id)object atIndexedSubscript:(NSUInteger)index; as weiran has shown for NS(Mutable)Array/NS(Mutable)Dictionary.
- skibrah 14y agoThat functionality is coming with Xcode 4.5
- lazerwalker 14y agoThe functionality is present for iOS, it just isn't being exposed. If you create a category header file (just header, not implementation) the compiler'll pick up on it and all will work fine. This isn't my code, but I've been happily using it for a week or so now: https://gist.github.com/3299750 https://gist.github.com/3299750
- pmjordan 14y agoNote that if you have 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);
- tolmasky 14y agoI've made that same macro, unfortunately the unboxing is the hard part because you don't know what type the NSValue contains. This is why I was hoping it would be a compiler feature because the compiler could use the surrounding info to figure it out: 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
- pmjordan 14y agoYeah, that would require type inference via the expression/return value though and not even C++ can do that (by and large anyway). But then ObjC as a language in general doesn't seem to care much for type safety anyway. I realise this makes objects quite flexible, but at the same time it's so, so easy to write code with undefined behaviour or with glaring security issues. I've actually come up with a typed variable binding macro for picking apart untrusted NSDictionaries (primarily from untrusted plists), which when used looks something like this: 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.