1*f4a2713aSLionel Sambuc==================== 2*f4a2713aSLionel SambucObjective-C Literals 3*f4a2713aSLionel Sambuc==================== 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel SambucIntroduction 6*f4a2713aSLionel Sambuc============ 7*f4a2713aSLionel Sambuc 8*f4a2713aSLionel SambucThree new features were introduced into clang at the same time: 9*f4a2713aSLionel Sambuc*NSNumber Literals* provide a syntax for creating ``NSNumber`` from 10*f4a2713aSLionel Sambucscalar literal expressions; *Collection Literals* provide a short-hand 11*f4a2713aSLionel Sambucfor creating arrays and dictionaries; *Object Subscripting* provides a 12*f4a2713aSLionel Sambucway to use subscripting with Objective-C objects. Users of Apple 13*f4a2713aSLionel Sambuccompiler releases can use these features starting with the Apple LLVM 14*f4a2713aSLionel SambucCompiler 4.0. Users of open-source LLVM.org compiler releases can use 15*f4a2713aSLionel Sambucthese features starting with clang v3.1. 16*f4a2713aSLionel Sambuc 17*f4a2713aSLionel SambucThese language additions simplify common Objective-C programming 18*f4a2713aSLionel Sambucpatterns, make programs more concise, and improve the safety of 19*f4a2713aSLionel Sambuccontainer creation. 20*f4a2713aSLionel Sambuc 21*f4a2713aSLionel SambucThis document describes how the features are implemented in clang, and 22*f4a2713aSLionel Sambuchow to use them in your own programs. 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel SambucNSNumber Literals 25*f4a2713aSLionel Sambuc================= 26*f4a2713aSLionel Sambuc 27*f4a2713aSLionel SambucThe framework class ``NSNumber`` is used to wrap scalar values inside 28*f4a2713aSLionel Sambucobjects: signed and unsigned integers (``char``, ``short``, ``int``, 29*f4a2713aSLionel Sambuc``long``, ``long long``), floating point numbers (``float``, 30*f4a2713aSLionel Sambuc``double``), and boolean values (``BOOL``, C++ ``bool``). Scalar values 31*f4a2713aSLionel Sambucwrapped in objects are also known as *boxed* values. 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel SambucIn Objective-C, any character, numeric or boolean literal prefixed with 34*f4a2713aSLionel Sambucthe ``'@'`` character will evaluate to a pointer to an ``NSNumber`` 35*f4a2713aSLionel Sambucobject initialized with that value. C's type suffixes may be used to 36*f4a2713aSLionel Sambuccontrol the size of numeric literals. 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel SambucExamples 39*f4a2713aSLionel Sambuc-------- 40*f4a2713aSLionel Sambuc 41*f4a2713aSLionel SambucThe following program illustrates the rules for ``NSNumber`` literals: 42*f4a2713aSLionel Sambuc 43*f4a2713aSLionel Sambuc.. code-block:: objc 44*f4a2713aSLionel Sambuc 45*f4a2713aSLionel Sambuc void main(int argc, const char *argv[]) { 46*f4a2713aSLionel Sambuc // character literals. 47*f4a2713aSLionel Sambuc NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z'] 48*f4a2713aSLionel Sambuc 49*f4a2713aSLionel Sambuc // integral literals. 50*f4a2713aSLionel Sambuc NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42] 51*f4a2713aSLionel Sambuc NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U] 52*f4a2713aSLionel Sambuc NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber numberWithLong:42L] 53*f4a2713aSLionel Sambuc NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL] 54*f4a2713aSLionel Sambuc 55*f4a2713aSLionel Sambuc // floating point literals. 56*f4a2713aSLionel Sambuc NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber numberWithFloat:3.141592654F] 57*f4a2713aSLionel Sambuc NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535] 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc // BOOL literals. 60*f4a2713aSLionel Sambuc NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES] 61*f4a2713aSLionel Sambuc NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO] 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc #ifdef __cplusplus 64*f4a2713aSLionel Sambuc NSNumber *trueNumber = @true; // equivalent to [NSNumber numberWithBool:(BOOL)true] 65*f4a2713aSLionel Sambuc NSNumber *falseNumber = @false; // equivalent to [NSNumber numberWithBool:(BOOL)false] 66*f4a2713aSLionel Sambuc #endif 67*f4a2713aSLionel Sambuc } 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel SambucDiscussion 70*f4a2713aSLionel Sambuc---------- 71*f4a2713aSLionel Sambuc 72*f4a2713aSLionel SambucNSNumber literals only support literal scalar values after the ``'@'``. 73*f4a2713aSLionel SambucConsequently, ``@INT_MAX`` works, but ``@INT_MIN`` does not, because 74*f4a2713aSLionel Sambucthey are defined like this: 75*f4a2713aSLionel Sambuc 76*f4a2713aSLionel Sambuc.. code-block:: objc 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc #define INT_MAX 2147483647 /* max value for an int */ 79*f4a2713aSLionel Sambuc #define INT_MIN (-2147483647-1) /* min value for an int */ 80*f4a2713aSLionel Sambuc 81*f4a2713aSLionel SambucThe definition of ``INT_MIN`` is not a simple literal, but a 82*f4a2713aSLionel Sambucparenthesized expression. Parenthesized expressions are supported using 83*f4a2713aSLionel Sambucthe `boxed expression <#objc_boxed_expressions>`_ syntax, which is 84*f4a2713aSLionel Sambucdescribed in the next section. 85*f4a2713aSLionel Sambuc 86*f4a2713aSLionel SambucBecause ``NSNumber`` does not currently support wrapping ``long double`` 87*f4a2713aSLionel Sambucvalues, the use of a ``long double NSNumber`` literal (e.g. 88*f4a2713aSLionel Sambuc``@123.23L``) will be rejected by the compiler. 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel SambucPreviously, the ``BOOL`` type was simply a typedef for ``signed char``, 91*f4a2713aSLionel Sambucand ``YES`` and ``NO`` were macros that expand to ``(BOOL)1`` and 92*f4a2713aSLionel Sambuc``(BOOL)0`` respectively. To support ``@YES`` and ``@NO`` expressions, 93*f4a2713aSLionel Sambucthese macros are now defined using new language keywords in 94*f4a2713aSLionel Sambuc``<objc/objc.h>``: 95*f4a2713aSLionel Sambuc 96*f4a2713aSLionel Sambuc.. code-block:: objc 97*f4a2713aSLionel Sambuc 98*f4a2713aSLionel Sambuc #if __has_feature(objc_bool) 99*f4a2713aSLionel Sambuc #define YES __objc_yes 100*f4a2713aSLionel Sambuc #define NO __objc_no 101*f4a2713aSLionel Sambuc #else 102*f4a2713aSLionel Sambuc #define YES ((BOOL)1) 103*f4a2713aSLionel Sambuc #define NO ((BOOL)0) 104*f4a2713aSLionel Sambuc #endif 105*f4a2713aSLionel Sambuc 106*f4a2713aSLionel SambucThe compiler implicitly converts ``__objc_yes`` and ``__objc_no`` to 107*f4a2713aSLionel Sambuc``(BOOL)1`` and ``(BOOL)0``. The keywords are used to disambiguate 108*f4a2713aSLionel Sambuc``BOOL`` and integer literals. 109*f4a2713aSLionel Sambuc 110*f4a2713aSLionel SambucObjective-C++ also supports ``@true`` and ``@false`` expressions, which 111*f4a2713aSLionel Sambucare equivalent to ``@YES`` and ``@NO``. 112*f4a2713aSLionel Sambuc 113*f4a2713aSLionel SambucBoxed Expressions 114*f4a2713aSLionel Sambuc================= 115*f4a2713aSLionel Sambuc 116*f4a2713aSLionel SambucObjective-C provides a new syntax for boxing C expressions: 117*f4a2713aSLionel Sambuc 118*f4a2713aSLionel Sambuc.. code-block:: objc 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc @( <expression> ) 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel SambucExpressions of scalar (numeric, enumerated, BOOL) and C string pointer 123*f4a2713aSLionel Sambuctypes are supported: 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc.. code-block:: objc 126*f4a2713aSLionel Sambuc 127*f4a2713aSLionel Sambuc // numbers. 128*f4a2713aSLionel Sambuc NSNumber *smallestInt = @(-INT_MAX - 1); // [NSNumber numberWithInt:(-INT_MAX - 1)] 129*f4a2713aSLionel Sambuc NSNumber *piOverTwo = @(M_PI / 2); // [NSNumber numberWithDouble:(M_PI / 2)] 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc // enumerated types. 132*f4a2713aSLionel Sambuc typedef enum { Red, Green, Blue } Color; 133*f4a2713aSLionel Sambuc NSNumber *favoriteColor = @(Green); // [NSNumber numberWithInt:((int)Green)] 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc // strings. 136*f4a2713aSLionel Sambuc NSString *path = @(getenv("PATH")); // [NSString stringWithUTF8String:(getenv("PATH"))] 137*f4a2713aSLionel Sambuc NSArray *pathComponents = [path componentsSeparatedByString:@":"]; 138*f4a2713aSLionel Sambuc 139*f4a2713aSLionel SambucBoxed Enums 140*f4a2713aSLionel Sambuc----------- 141*f4a2713aSLionel Sambuc 142*f4a2713aSLionel SambucCocoa frameworks frequently define constant values using *enums.* 143*f4a2713aSLionel SambucAlthough enum values are integral, they may not be used directly as 144*f4a2713aSLionel Sambucboxed literals (this avoids conflicts with future ``'@'``-prefixed 145*f4a2713aSLionel SambucObjective-C keywords). Instead, an enum value must be placed inside a 146*f4a2713aSLionel Sambucboxed expression. The following example demonstrates configuring an 147*f4a2713aSLionel Sambuc``AVAudioRecorder`` using a dictionary that contains a boxed enumeration 148*f4a2713aSLionel Sambucvalue: 149*f4a2713aSLionel Sambuc 150*f4a2713aSLionel Sambuc.. code-block:: objc 151*f4a2713aSLionel Sambuc 152*f4a2713aSLionel Sambuc enum { 153*f4a2713aSLionel Sambuc AVAudioQualityMin = 0, 154*f4a2713aSLionel Sambuc AVAudioQualityLow = 0x20, 155*f4a2713aSLionel Sambuc AVAudioQualityMedium = 0x40, 156*f4a2713aSLionel Sambuc AVAudioQualityHigh = 0x60, 157*f4a2713aSLionel Sambuc AVAudioQualityMax = 0x7F 158*f4a2713aSLionel Sambuc }; 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc - (AVAudioRecorder *)recordToFile:(NSURL *)fileURL { 161*f4a2713aSLionel Sambuc NSDictionary *settings = @{ AVEncoderAudioQualityKey : @(AVAudioQualityMax) }; 162*f4a2713aSLionel Sambuc return [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:NULL]; 163*f4a2713aSLionel Sambuc } 164*f4a2713aSLionel Sambuc 165*f4a2713aSLionel SambucThe expression ``@(AVAudioQualityMax)`` converts ``AVAudioQualityMax`` 166*f4a2713aSLionel Sambucto an integer type, and boxes the value accordingly. If the enum has a 167*f4a2713aSLionel Sambuc:ref:`fixed underlying type <objc-fixed-enum>` as in: 168*f4a2713aSLionel Sambuc 169*f4a2713aSLionel Sambuc.. code-block:: objc 170*f4a2713aSLionel Sambuc 171*f4a2713aSLionel Sambuc typedef enum : unsigned char { Red, Green, Blue } Color; 172*f4a2713aSLionel Sambuc NSNumber *red = @(Red), *green = @(Green), *blue = @(Blue); // => [NSNumber numberWithUnsignedChar:] 173*f4a2713aSLionel Sambuc 174*f4a2713aSLionel Sambucthen the fixed underlying type will be used to select the correct 175*f4a2713aSLionel Sambuc``NSNumber`` creation method. 176*f4a2713aSLionel Sambuc 177*f4a2713aSLionel SambucBoxing a value of enum type will result in a ``NSNumber`` pointer with a 178*f4a2713aSLionel Sambuccreation method according to the underlying type of the enum, which can 179*f4a2713aSLionel Sambucbe a :ref:`fixed underlying type <objc-fixed-enum>` 180*f4a2713aSLionel Sambucor a compiler-defined integer type capable of representing the values of 181*f4a2713aSLionel Sambucall the members of the enumeration: 182*f4a2713aSLionel Sambuc 183*f4a2713aSLionel Sambuc.. code-block:: objc 184*f4a2713aSLionel Sambuc 185*f4a2713aSLionel Sambuc typedef enum : unsigned char { Red, Green, Blue } Color; 186*f4a2713aSLionel Sambuc Color col = Red; 187*f4a2713aSLionel Sambuc NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:] 188*f4a2713aSLionel Sambuc 189*f4a2713aSLionel SambucBoxed C Strings 190*f4a2713aSLionel Sambuc--------------- 191*f4a2713aSLionel Sambuc 192*f4a2713aSLionel SambucA C string literal prefixed by the ``'@'`` token denotes an ``NSString`` 193*f4a2713aSLionel Sambucliteral in the same way a numeric literal prefixed by the ``'@'`` token 194*f4a2713aSLionel Sambucdenotes an ``NSNumber`` literal. When the type of the parenthesized 195*f4a2713aSLionel Sambucexpression is ``(char *)`` or ``(const char *)``, the result of the 196*f4a2713aSLionel Sambucboxed expression is a pointer to an ``NSString`` object containing 197*f4a2713aSLionel Sambucequivalent character data, which is assumed to be '\\0'-terminated and 198*f4a2713aSLionel SambucUTF-8 encoded. The following example converts C-style command line 199*f4a2713aSLionel Sambucarguments into ``NSString`` objects. 200*f4a2713aSLionel Sambuc 201*f4a2713aSLionel Sambuc.. code-block:: objc 202*f4a2713aSLionel Sambuc 203*f4a2713aSLionel Sambuc // Partition command line arguments into positional and option arguments. 204*f4a2713aSLionel Sambuc NSMutableArray *args = [NSMutableArray new]; 205*f4a2713aSLionel Sambuc NSMutableDictionary *options = [NSMutableDictionary new]; 206*f4a2713aSLionel Sambuc while (--argc) { 207*f4a2713aSLionel Sambuc const char *arg = *++argv; 208*f4a2713aSLionel Sambuc if (strncmp(arg, "--", 2) == 0) { 209*f4a2713aSLionel Sambuc options[@(arg + 2)] = @(*++argv); // --key value 210*f4a2713aSLionel Sambuc } else { 211*f4a2713aSLionel Sambuc [args addObject:@(arg)]; // positional argument 212*f4a2713aSLionel Sambuc } 213*f4a2713aSLionel Sambuc } 214*f4a2713aSLionel Sambuc 215*f4a2713aSLionel SambucAs with all C pointers, character pointer expressions can involve 216*f4a2713aSLionel Sambucarbitrary pointer arithmetic, therefore programmers must ensure that the 217*f4a2713aSLionel Sambuccharacter data is valid. Passing ``NULL`` as the character pointer will 218*f4a2713aSLionel Sambucraise an exception at runtime. When possible, the compiler will reject 219*f4a2713aSLionel Sambuc``NULL`` character pointers used in boxed expressions. 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel SambucContainer Literals 222*f4a2713aSLionel Sambuc================== 223*f4a2713aSLionel Sambuc 224*f4a2713aSLionel SambucObjective-C now supports a new expression syntax for creating immutable 225*f4a2713aSLionel Sambucarray and dictionary container objects. 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel SambucExamples 228*f4a2713aSLionel Sambuc-------- 229*f4a2713aSLionel Sambuc 230*f4a2713aSLionel SambucImmutable array expression: 231*f4a2713aSLionel Sambuc 232*f4a2713aSLionel Sambuc.. code-block:: objc 233*f4a2713aSLionel Sambuc 234*f4a2713aSLionel Sambuc NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ]; 235*f4a2713aSLionel Sambuc 236*f4a2713aSLionel SambucThis creates an ``NSArray`` with 3 elements. The comma-separated 237*f4a2713aSLionel Sambucsub-expressions of an array literal can be any Objective-C object 238*f4a2713aSLionel Sambucpointer typed expression. 239*f4a2713aSLionel Sambuc 240*f4a2713aSLionel SambucImmutable dictionary expression: 241*f4a2713aSLionel Sambuc 242*f4a2713aSLionel Sambuc.. code-block:: objc 243*f4a2713aSLionel Sambuc 244*f4a2713aSLionel Sambuc NSDictionary *dictionary = @{ 245*f4a2713aSLionel Sambuc @"name" : NSUserName(), 246*f4a2713aSLionel Sambuc @"date" : [NSDate date], 247*f4a2713aSLionel Sambuc @"processInfo" : [NSProcessInfo processInfo] 248*f4a2713aSLionel Sambuc }; 249*f4a2713aSLionel Sambuc 250*f4a2713aSLionel SambucThis creates an ``NSDictionary`` with 3 key/value pairs. Value 251*f4a2713aSLionel Sambucsub-expressions of a dictionary literal must be Objective-C object 252*f4a2713aSLionel Sambucpointer typed, as in array literals. Key sub-expressions must be of an 253*f4a2713aSLionel SambucObjective-C object pointer type that implements the 254*f4a2713aSLionel Sambuc``<NSCopying>`` protocol. 255*f4a2713aSLionel Sambuc 256*f4a2713aSLionel SambucDiscussion 257*f4a2713aSLionel Sambuc---------- 258*f4a2713aSLionel Sambuc 259*f4a2713aSLionel SambucNeither keys nor values can have the value ``nil`` in containers. If the 260*f4a2713aSLionel Sambuccompiler can prove that a key or value is ``nil`` at compile time, then 261*f4a2713aSLionel Sambuca warning will be emitted. Otherwise, a runtime error will occur. 262*f4a2713aSLionel Sambuc 263*f4a2713aSLionel SambucUsing array and dictionary literals is safer than the variadic creation 264*f4a2713aSLionel Sambucforms commonly in use today. Array literal expressions expand to calls 265*f4a2713aSLionel Sambucto ``+[NSArray arrayWithObjects:count:]``, which validates that all 266*f4a2713aSLionel Sambucobjects are non-``nil``. The variadic form, 267*f4a2713aSLionel Sambuc``+[NSArray arrayWithObjects:]`` uses ``nil`` as an argument list 268*f4a2713aSLionel Sambucterminator, which can lead to malformed array objects. Dictionary 269*f4a2713aSLionel Sambucliterals are similarly created with 270*f4a2713aSLionel Sambuc``+[NSDictionary dictionaryWithObjects:forKeys:count:]`` which validates 271*f4a2713aSLionel Sambucall objects and keys, unlike 272*f4a2713aSLionel Sambuc``+[NSDictionary dictionaryWithObjectsAndKeys:]`` which also uses a 273*f4a2713aSLionel Sambuc``nil`` parameter as an argument list terminator. 274*f4a2713aSLionel Sambuc 275*f4a2713aSLionel SambucObject Subscripting 276*f4a2713aSLionel Sambuc=================== 277*f4a2713aSLionel Sambuc 278*f4a2713aSLionel SambucObjective-C object pointer values can now be used with C's subscripting 279*f4a2713aSLionel Sambucoperator. 280*f4a2713aSLionel Sambuc 281*f4a2713aSLionel SambucExamples 282*f4a2713aSLionel Sambuc-------- 283*f4a2713aSLionel Sambuc 284*f4a2713aSLionel SambucThe following code demonstrates the use of object subscripting syntax 285*f4a2713aSLionel Sambucwith ``NSMutableArray`` and ``NSMutableDictionary`` objects: 286*f4a2713aSLionel Sambuc 287*f4a2713aSLionel Sambuc.. code-block:: objc 288*f4a2713aSLionel Sambuc 289*f4a2713aSLionel Sambuc NSMutableArray *array = ...; 290*f4a2713aSLionel Sambuc NSUInteger idx = ...; 291*f4a2713aSLionel Sambuc id newObject = ...; 292*f4a2713aSLionel Sambuc id oldObject = array[idx]; 293*f4a2713aSLionel Sambuc array[idx] = newObject; // replace oldObject with newObject 294*f4a2713aSLionel Sambuc 295*f4a2713aSLionel Sambuc NSMutableDictionary *dictionary = ...; 296*f4a2713aSLionel Sambuc NSString *key = ...; 297*f4a2713aSLionel Sambuc oldObject = dictionary[key]; 298*f4a2713aSLionel Sambuc dictionary[key] = newObject; // replace oldObject with newObject 299*f4a2713aSLionel Sambuc 300*f4a2713aSLionel SambucThe next section explains how subscripting expressions map to accessor 301*f4a2713aSLionel Sambucmethods. 302*f4a2713aSLionel Sambuc 303*f4a2713aSLionel SambucSubscripting Methods 304*f4a2713aSLionel Sambuc-------------------- 305*f4a2713aSLionel Sambuc 306*f4a2713aSLionel SambucObjective-C supports two kinds of subscript expressions: *array-style* 307*f4a2713aSLionel Sambucsubscript expressions use integer typed subscripts; *dictionary-style* 308*f4a2713aSLionel Sambucsubscript expressions use Objective-C object pointer typed subscripts. 309*f4a2713aSLionel SambucEach type of subscript expression is mapped to a message send using a 310*f4a2713aSLionel Sambucpredefined selector. The advantage of this design is flexibility: class 311*f4a2713aSLionel Sambucdesigners are free to introduce subscripting by declaring methods or by 312*f4a2713aSLionel Sambucadopting protocols. Moreover, because the method names are selected by 313*f4a2713aSLionel Sambucthe type of the subscript, an object can be subscripted using both array 314*f4a2713aSLionel Sambucand dictionary styles. 315*f4a2713aSLionel Sambuc 316*f4a2713aSLionel SambucArray-Style Subscripting 317*f4a2713aSLionel Sambuc^^^^^^^^^^^^^^^^^^^^^^^^ 318*f4a2713aSLionel Sambuc 319*f4a2713aSLionel SambucWhen the subscript operand has an integral type, the expression is 320*f4a2713aSLionel Sambucrewritten to use one of two different selectors, depending on whether 321*f4a2713aSLionel Sambucthe element is being read or written. When an expression reads an 322*f4a2713aSLionel Sambucelement using an integral index, as in the following example: 323*f4a2713aSLionel Sambuc 324*f4a2713aSLionel Sambuc.. code-block:: objc 325*f4a2713aSLionel Sambuc 326*f4a2713aSLionel Sambuc NSUInteger idx = ...; 327*f4a2713aSLionel Sambuc id value = object[idx]; 328*f4a2713aSLionel Sambuc 329*f4a2713aSLionel Sambucit is translated into a call to ``objectAtIndexedSubscript:`` 330*f4a2713aSLionel Sambuc 331*f4a2713aSLionel Sambuc.. code-block:: objc 332*f4a2713aSLionel Sambuc 333*f4a2713aSLionel Sambuc id value = [object objectAtIndexedSubscript:idx]; 334*f4a2713aSLionel Sambuc 335*f4a2713aSLionel SambucWhen an expression writes an element using an integral index: 336*f4a2713aSLionel Sambuc 337*f4a2713aSLionel Sambuc.. code-block:: objc 338*f4a2713aSLionel Sambuc 339*f4a2713aSLionel Sambuc object[idx] = newValue; 340*f4a2713aSLionel Sambuc 341*f4a2713aSLionel Sambucit is translated to a call to ``setObject:atIndexedSubscript:`` 342*f4a2713aSLionel Sambuc 343*f4a2713aSLionel Sambuc.. code-block:: objc 344*f4a2713aSLionel Sambuc 345*f4a2713aSLionel Sambuc [object setObject:newValue atIndexedSubscript:idx]; 346*f4a2713aSLionel Sambuc 347*f4a2713aSLionel SambucThese message sends are then type-checked and performed just like 348*f4a2713aSLionel Sambucexplicit message sends. The method used for objectAtIndexedSubscript: 349*f4a2713aSLionel Sambucmust be declared with an argument of integral type and a return value of 350*f4a2713aSLionel Sambucsome Objective-C object pointer type. The method used for 351*f4a2713aSLionel SambucsetObject:atIndexedSubscript: must be declared with its first argument 352*f4a2713aSLionel Sambuchaving some Objective-C pointer type and its second argument having 353*f4a2713aSLionel Sambucintegral type. 354*f4a2713aSLionel Sambuc 355*f4a2713aSLionel SambucThe meaning of indexes is left up to the declaring class. The compiler 356*f4a2713aSLionel Sambucwill coerce the index to the appropriate argument type of the method it 357*f4a2713aSLionel Sambucuses for type-checking. For an instance of ``NSArray``, reading an 358*f4a2713aSLionel Sambucelement using an index outside the range ``[0, array.count)`` will raise 359*f4a2713aSLionel Sambucan exception. For an instance of ``NSMutableArray``, assigning to an 360*f4a2713aSLionel Sambucelement using an index within this range will replace that element, but 361*f4a2713aSLionel Sambucassigning to an element using an index outside this range will raise an 362*f4a2713aSLionel Sambucexception; no syntax is provided for inserting, appending, or removing 363*f4a2713aSLionel Sambucelements for mutable arrays. 364*f4a2713aSLionel Sambuc 365*f4a2713aSLionel SambucA class need not declare both methods in order to take advantage of this 366*f4a2713aSLionel Sambuclanguage feature. For example, the class ``NSArray`` declares only 367*f4a2713aSLionel Sambuc``objectAtIndexedSubscript:``, so that assignments to elements will fail 368*f4a2713aSLionel Sambucto type-check; moreover, its subclass ``NSMutableArray`` declares 369*f4a2713aSLionel Sambuc``setObject:atIndexedSubscript:``. 370*f4a2713aSLionel Sambuc 371*f4a2713aSLionel SambucDictionary-Style Subscripting 372*f4a2713aSLionel Sambuc^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 373*f4a2713aSLionel Sambuc 374*f4a2713aSLionel SambucWhen the subscript operand has an Objective-C object pointer type, the 375*f4a2713aSLionel Sambucexpression is rewritten to use one of two different selectors, depending 376*f4a2713aSLionel Sambucon whether the element is being read from or written to. When an 377*f4a2713aSLionel Sambucexpression reads an element using an Objective-C object pointer 378*f4a2713aSLionel Sambucsubscript operand, as in the following example: 379*f4a2713aSLionel Sambuc 380*f4a2713aSLionel Sambuc.. code-block:: objc 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc id key = ...; 383*f4a2713aSLionel Sambuc id value = object[key]; 384*f4a2713aSLionel Sambuc 385*f4a2713aSLionel Sambucit is translated into a call to the ``objectForKeyedSubscript:`` method: 386*f4a2713aSLionel Sambuc 387*f4a2713aSLionel Sambuc.. code-block:: objc 388*f4a2713aSLionel Sambuc 389*f4a2713aSLionel Sambuc id value = [object objectForKeyedSubscript:key]; 390*f4a2713aSLionel Sambuc 391*f4a2713aSLionel SambucWhen an expression writes an element using an Objective-C object pointer 392*f4a2713aSLionel Sambucsubscript: 393*f4a2713aSLionel Sambuc 394*f4a2713aSLionel Sambuc.. code-block:: objc 395*f4a2713aSLionel Sambuc 396*f4a2713aSLionel Sambuc object[key] = newValue; 397*f4a2713aSLionel Sambuc 398*f4a2713aSLionel Sambucit is translated to a call to ``setObject:forKeyedSubscript:`` 399*f4a2713aSLionel Sambuc 400*f4a2713aSLionel Sambuc.. code-block:: objc 401*f4a2713aSLionel Sambuc 402*f4a2713aSLionel Sambuc [object setObject:newValue forKeyedSubscript:key]; 403*f4a2713aSLionel Sambuc 404*f4a2713aSLionel SambucThe behavior of ``setObject:forKeyedSubscript:`` is class-specific; but 405*f4a2713aSLionel Sambucin general it should replace an existing value if one is already 406*f4a2713aSLionel Sambucassociated with a key, otherwise it should add a new value for the key. 407*f4a2713aSLionel SambucNo syntax is provided for removing elements from mutable dictionaries. 408*f4a2713aSLionel Sambuc 409*f4a2713aSLionel SambucDiscussion 410*f4a2713aSLionel Sambuc---------- 411*f4a2713aSLionel Sambuc 412*f4a2713aSLionel SambucAn Objective-C subscript expression occurs when the base operand of the 413*f4a2713aSLionel SambucC subscript operator has an Objective-C object pointer type. Since this 414*f4a2713aSLionel Sambucpotentially collides with pointer arithmetic on the value, these 415*f4a2713aSLionel Sambucexpressions are only supported under the modern Objective-C runtime, 416*f4a2713aSLionel Sambucwhich categorically forbids such arithmetic. 417*f4a2713aSLionel Sambuc 418*f4a2713aSLionel SambucCurrently, only subscripts of integral or Objective-C object pointer 419*f4a2713aSLionel Sambuctype are supported. In C++, a class type can be used if it has a single 420*f4a2713aSLionel Sambucconversion function to an integral or Objective-C pointer type, in which 421*f4a2713aSLionel Sambuccase that conversion is applied and analysis continues as appropriate. 422*f4a2713aSLionel SambucOtherwise, the expression is ill-formed. 423*f4a2713aSLionel Sambuc 424*f4a2713aSLionel SambucAn Objective-C object subscript expression is always an l-value. If the 425*f4a2713aSLionel Sambucexpression appears on the left-hand side of a simple assignment operator 426*f4a2713aSLionel Sambuc(=), the element is written as described below. If the expression 427*f4a2713aSLionel Sambucappears on the left-hand side of a compound assignment operator (e.g. 428*f4a2713aSLionel Sambuc+=), the program is ill-formed, because the result of reading an element 429*f4a2713aSLionel Sambucis always an Objective-C object pointer and no binary operators are 430*f4a2713aSLionel Sambuclegal on such pointers. If the expression appears in any other position, 431*f4a2713aSLionel Sambucthe element is read as described below. It is an error to take the 432*f4a2713aSLionel Sambucaddress of a subscript expression, or (in C++) to bind a reference to 433*f4a2713aSLionel Sambucit. 434*f4a2713aSLionel Sambuc 435*f4a2713aSLionel SambucPrograms can use object subscripting with Objective-C object pointers of 436*f4a2713aSLionel Sambuctype ``id``. Normal dynamic message send rules apply; the compiler must 437*f4a2713aSLionel Sambucsee *some* declaration of the subscripting methods, and will pick the 438*f4a2713aSLionel Sambucdeclaration seen first. 439*f4a2713aSLionel Sambuc 440*f4a2713aSLionel SambucCaveats 441*f4a2713aSLionel Sambuc======= 442*f4a2713aSLionel Sambuc 443*f4a2713aSLionel SambucObjects created using the literal or boxed expression syntax are not 444*f4a2713aSLionel Sambucguaranteed to be uniqued by the runtime, but nor are they guaranteed to 445*f4a2713aSLionel Sambucbe newly-allocated. As such, the result of performing direct comparisons 446*f4a2713aSLionel Sambucagainst the location of an object literal (using ``==``, ``!=``, ``<``, 447*f4a2713aSLionel Sambuc``<=``, ``>``, or ``>=``) is not well-defined. This is usually a simple 448*f4a2713aSLionel Sambucmistake in code that intended to call the ``isEqual:`` method (or the 449*f4a2713aSLionel Sambuc``compare:`` method). 450*f4a2713aSLionel Sambuc 451*f4a2713aSLionel SambucThis caveat applies to compile-time string literals as well. 452*f4a2713aSLionel SambucHistorically, string literals (using the ``@"..."`` syntax) have been 453*f4a2713aSLionel Sambucuniqued across translation units during linking. This is an 454*f4a2713aSLionel Sambucimplementation detail of the compiler and should not be relied upon. If 455*f4a2713aSLionel Sambucyou are using such code, please use global string constants instead 456*f4a2713aSLionel Sambuc(``NSString * const MyConst = @"..."``) or use ``isEqual:``. 457*f4a2713aSLionel Sambuc 458*f4a2713aSLionel SambucGrammar Additions 459*f4a2713aSLionel Sambuc================= 460*f4a2713aSLionel Sambuc 461*f4a2713aSLionel SambucTo support the new syntax described above, the Objective-C 462*f4a2713aSLionel Sambuc``@``-expression grammar has the following new productions: 463*f4a2713aSLionel Sambuc 464*f4a2713aSLionel Sambuc:: 465*f4a2713aSLionel Sambuc 466*f4a2713aSLionel Sambuc objc-at-expression : '@' (string-literal | encode-literal | selector-literal | protocol-literal | object-literal) 467*f4a2713aSLionel Sambuc ; 468*f4a2713aSLionel Sambuc 469*f4a2713aSLionel Sambuc object-literal : ('+' | '-')? numeric-constant 470*f4a2713aSLionel Sambuc | character-constant 471*f4a2713aSLionel Sambuc | boolean-constant 472*f4a2713aSLionel Sambuc | array-literal 473*f4a2713aSLionel Sambuc | dictionary-literal 474*f4a2713aSLionel Sambuc ; 475*f4a2713aSLionel Sambuc 476*f4a2713aSLionel Sambuc boolean-constant : '__objc_yes' | '__objc_no' | 'true' | 'false' /* boolean keywords. */ 477*f4a2713aSLionel Sambuc ; 478*f4a2713aSLionel Sambuc 479*f4a2713aSLionel Sambuc array-literal : '[' assignment-expression-list ']' 480*f4a2713aSLionel Sambuc ; 481*f4a2713aSLionel Sambuc 482*f4a2713aSLionel Sambuc assignment-expression-list : assignment-expression (',' assignment-expression-list)? 483*f4a2713aSLionel Sambuc | /* empty */ 484*f4a2713aSLionel Sambuc ; 485*f4a2713aSLionel Sambuc 486*f4a2713aSLionel Sambuc dictionary-literal : '{' key-value-list '}' 487*f4a2713aSLionel Sambuc ; 488*f4a2713aSLionel Sambuc 489*f4a2713aSLionel Sambuc key-value-list : key-value-pair (',' key-value-list)? 490*f4a2713aSLionel Sambuc | /* empty */ 491*f4a2713aSLionel Sambuc ; 492*f4a2713aSLionel Sambuc 493*f4a2713aSLionel Sambuc key-value-pair : assignment-expression ':' assignment-expression 494*f4a2713aSLionel Sambuc ; 495*f4a2713aSLionel Sambuc 496*f4a2713aSLionel SambucNote: ``@true`` and ``@false`` are only supported in Objective-C++. 497*f4a2713aSLionel Sambuc 498*f4a2713aSLionel SambucAvailability Checks 499*f4a2713aSLionel Sambuc=================== 500*f4a2713aSLionel Sambuc 501*f4a2713aSLionel SambucPrograms test for the new features by using clang's \_\_has\_feature 502*f4a2713aSLionel Sambucchecks. Here are examples of their use: 503*f4a2713aSLionel Sambuc 504*f4a2713aSLionel Sambuc.. code-block:: objc 505*f4a2713aSLionel Sambuc 506*f4a2713aSLionel Sambuc #if __has_feature(objc_array_literals) 507*f4a2713aSLionel Sambuc // new way. 508*f4a2713aSLionel Sambuc NSArray *elements = @[ @"H", @"He", @"O", @"C" ]; 509*f4a2713aSLionel Sambuc #else 510*f4a2713aSLionel Sambuc // old way (equivalent). 511*f4a2713aSLionel Sambuc id objects[] = { @"H", @"He", @"O", @"C" }; 512*f4a2713aSLionel Sambuc NSArray *elements = [NSArray arrayWithObjects:objects count:4]; 513*f4a2713aSLionel Sambuc #endif 514*f4a2713aSLionel Sambuc 515*f4a2713aSLionel Sambuc #if __has_feature(objc_dictionary_literals) 516*f4a2713aSLionel Sambuc // new way. 517*f4a2713aSLionel Sambuc NSDictionary *masses = @{ @"H" : @1.0078, @"He" : @4.0026, @"O" : @15.9990, @"C" : @12.0096 }; 518*f4a2713aSLionel Sambuc #else 519*f4a2713aSLionel Sambuc // old way (equivalent). 520*f4a2713aSLionel Sambuc id keys[] = { @"H", @"He", @"O", @"C" }; 521*f4a2713aSLionel Sambuc id values[] = { [NSNumber numberWithDouble:1.0078], [NSNumber numberWithDouble:4.0026], 522*f4a2713aSLionel Sambuc [NSNumber numberWithDouble:15.9990], [NSNumber numberWithDouble:12.0096] }; 523*f4a2713aSLionel Sambuc NSDictionary *masses = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:4]; 524*f4a2713aSLionel Sambuc #endif 525*f4a2713aSLionel Sambuc 526*f4a2713aSLionel Sambuc #if __has_feature(objc_subscripting) 527*f4a2713aSLionel Sambuc NSUInteger i, count = elements.count; 528*f4a2713aSLionel Sambuc for (i = 0; i < count; ++i) { 529*f4a2713aSLionel Sambuc NSString *element = elements[i]; 530*f4a2713aSLionel Sambuc NSNumber *mass = masses[element]; 531*f4a2713aSLionel Sambuc NSLog(@"the mass of %@ is %@", element, mass); 532*f4a2713aSLionel Sambuc } 533*f4a2713aSLionel Sambuc #else 534*f4a2713aSLionel Sambuc NSUInteger i, count = [elements count]; 535*f4a2713aSLionel Sambuc for (i = 0; i < count; ++i) { 536*f4a2713aSLionel Sambuc NSString *element = [elements objectAtIndex:i]; 537*f4a2713aSLionel Sambuc NSNumber *mass = [masses objectForKey:element]; 538*f4a2713aSLionel Sambuc NSLog(@"the mass of %@ is %@", element, mass); 539*f4a2713aSLionel Sambuc } 540*f4a2713aSLionel Sambuc #endif 541*f4a2713aSLionel Sambuc 542*f4a2713aSLionel SambucCode can use also ``__has_feature(objc_bool)`` to check for the 543*f4a2713aSLionel Sambucavailability of numeric literals support. This checks for the new 544*f4a2713aSLionel Sambuc``__objc_yes / __objc_no`` keywords, which enable the use of 545*f4a2713aSLionel Sambuc``@YES / @NO`` literals. 546*f4a2713aSLionel Sambuc 547*f4a2713aSLionel SambucTo check whether boxed expressions are supported, use 548*f4a2713aSLionel Sambuc``__has_feature(objc_boxed_expressions)`` feature macro. 549