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