From: Patrick Beard
Clang provides support for Object Literals and Subscripting in Objective-C, which simplifies common Objective-C programming patterns, makes programs more concise, and improves the safety of container creation. There are several feature macros associated with object literals and subscripting: __has_feature(objc_array_literals)
tests the availability of array literals; __has_feature(objc_dictionary_literals)
tests the availability of dictionary literals; __has_feature(objc_subscripting)
tests the availability of object subscripting.
Clang provides support for Object Literals
+and Subscripting in Objective-C, which simplifies common Objective-C
+programming patterns, makes programs more concise, and improves the safety of
+container creation. There are several feature macros associated with object
+literals and subscripting: __has_feature(objc_array_literals)
+tests the availability of array literals;
+__has_feature(objc_dictionary_literals)
tests the availability of
+dictionary literals; __has_feature(objc_subscripting)
tests the
+availability of object subscripting.
+NSNumber literals only support literal scalar values after the '@'
. Consequently, @INT_MAX
works, but @INT_MIN
does not, because they are defined like this:
#define INT_MAX 2147483647 /* max value for an int */ #define INT_MIN (-2147483647-1) /* min value for an int */-The definition of INT_MIN is not a simple literal, but a parenthesized expression. This is by design, but may be improved in subsequent compiler releases.
+The definition of INT_MIN
is not a simple literal, but a parenthesized expression. Parenthesized
+expressions are supported using the boxed expression syntax, which is described in the next section.
Because NSNumber
does not currently support wrapping long double
values, the use of a long double NSNumber
literal (e.g. @123.23L
) will be rejected by the compiler.
@@ -95,6 +96,94 @@ The compiler implicitly converts __objc_yes
and __objc_no@true
and @false
expressions, which are equivalent to @YES
and @NO
.
+
+
Objective-C provides a new syntax for boxing C expressions:
+ +
+@( expression )
+
+
+Expressions of scalar (numeric, enumerated, BOOL) and C string pointer types +are supported:
+ ++// numbers. +NSNumber *smallestInt = @(-INT_MAX - 1); +NSNumber *piOverTwo = @(M_PI / 2); + +// enumerated types. +typedef enum { Red, Green, Blue } Color; +NSNumber *favoriteColor = @(Green); + +// strings. +NSString *path = @(getenv("PATH")); +NSArray *pathComponents = [path componentsSeparatedByString:@":"]; ++ +
+Cocoa frameworks frequently define constant values using enums. Although enum values are integral, they may not be used directly as boxed literals (this avoids conflicts with future '@'
-prefixed Objective-C keywords). Instead, an enum value must be placed inside a boxed expression. The following example demonstrates configuring an AVAudioRecorder
using a dictionary that contains a boxed enumeration value:
+
+enum { + AVAudioQualityMin = 0, + AVAudioQualityLow = 0x20, + AVAudioQualityMedium = 0x40, + AVAudioQualityHigh = 0x60, + AVAudioQualityMax = 0x7F +}; + +- (AVAudioRecorder *)recordToFile:(NSURL *)fileURL { + NSDictionary *settings = @{ AVEncoderAudioQualityKey : @(AVAudioQualityMax) }; + return [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:NULL]; +} ++ +
+The expression @(AVAudioQualityMax)
converts AVAudioQualityMax
to an integer type, and boxes the value accordingly. If the enum has a fixed underlying type as in:
+
+typedef enum : unsigned char { Red, Green, Blue } Color; +NSNumber *red = @(Red), *green = @(Green), *blue = @(Blue); // => [NSNumber numberWithUnsignedChar:] ++ +
+then the fixed underlying type will be used to select the correct NSNumber
creation method.
+
+A C string literal prefixed by the '@'
token denotes an NSString
literal in the same way a numeric literal prefixed by the '@'
token denotes an NSNumber
literal. When the type of the parenthesized expression is (char *)
or (const char *)
, the result of the boxed expression is a pointer to an NSString
object containing equivalent character data. The following example converts C-style command line arguments into NSString
objects.
+
+// Partition command line arguments into positional and option arguments. +NSMutableArray *args = [NSMutableArray new]; +NSMutableDictionary *options = [NSMutableArray new]; +while (--argc) { + const char *arg = *++argv; + if (strncmp(arg, "--", 2) == 0) { + options[@(arg + 2)] = @(*++argv); // --key value + } else { + [args addObject:@(arg)]; // positional argument + } +} ++ +
+As with all C pointers, character pointer expressions can involve arbitrary pointer arithmetic, therefore programmers must ensure that the character data is valid. Passing NULL
as the character pointer will raise an exception at runtime. When possible, the compiler will reject NULL
character pointers used in boxed expressions.
+
This feature will be available in clang 3.2. It is not currently available in any Apple compiler.
-
++This creates anNSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];+NSArray
with 3 elements. The comma-separated sub-expressions of an array literal can be any Objective-C object pointer typed expression.@@ -309,6 +400,9 @@ Programs test for the new features by using clang's __has_feature checks. Here a Code can use also
__has_feature(objc_bool)
to check for the availability of numeric literals support. This checks for the new__objc_yes / __objc_no
keywords, which enable the use of@YES / @NO
literals.+
To check whether boxed expressions are supported, use +
+__has_feature(objc_boxed_expressions)
feature macro.