Каковы подробности "Objective-C Literals", упомянутые в примечаниях к выпуску Xcode 4.4?
Я просматривал заметки о выпуске для Xcode 4.4 и заметил это:
Компилятор LLVM 4.0
Xcode теперь включает в себя Apple LLVM Compiler версии 4.0, включая следующие новые функции языка Objective-C: [...]
- Литералы Objective C: создайте литералы для NSArray, NSDictionary и NSNumber, точно так же, как литералы для NSString
Я заинтригован об этой функции. Мне не совсем понятно, как буквально NSString
работать и как их можно использовать на NSArray
, NSDictionary
, а также NSNumber
,
Какие детали?
4 ответа
Скопировано дословно с http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and:
Литералы Objective C: теперь можно создавать литералы для NSArray, NSDictionary и NSNumber (точно так же, как можно создавать литералы для NSString)
NSArray Литералы
Ранее:
array = [NSArray arrayWithObjects:a, b, c, nil];
Сейчас:
array = @[ a, b, c ];
NSDictionary Литералы
Ранее:
dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3]
forKeys:@[k1, k2, k3]];
Сейчас:
dict = @{ k1 : o1, k2 : o2, k3 : o3 };
NSNumber Литералы
Ранее:
NSNumber *number;
number = [NSNumber numberWithChar:'X'];
number = [NSNumber numberWithInt:12345];
number = [NSNumber numberWithUnsignedLong:12345ul];
number = [NSNumber numberWithLongLong:12345ll];
number = [NSNumber numberWithFloat:123.45f];
number = [NSNumber numberWithDouble:123.45];
number = [NSNumber numberWithBool:YES];
Сейчас:
NSNumber *number;
number = @'X';
number = @12345;
number = @12345ul;
number = @12345ll;
number = @123.45f;
number = @123.45;
number = @YES;
[Редактировать]
zxoq на http://news.ycombinator.com/item?id=3672744 добавил более интересные новые подписки. (Добавлено с литералами):
arr[1] === [arr objectAtIndex:1]
dict[@"key"] === [dict objectForKey:@"key"]
[Редактировать 2]
Новые литералы ObjC обсуждались на нескольких сессиях WWDC 2012. Я специально не удалил имена файлов и время каждого слайда, чтобы вы могли найти их сами, если захотите. По сути, это то же самое, что указано в этом посте, но есть также несколько новых вещей, которые я упомяну над изображениями.
Обратите внимание, что изображения все большие. Просто перетащите их на другую вкладку, чтобы просмотреть их в оригинальном размере
[NSNumber numberWithint:42]
[NSNumber numberWithDouble:10.8]
[NSNumber numberWithBool:YES]
[NSNumber numberWithint:6 + x * 2012]
@42
@10.8
@YES
@(6 + x * 2012)
[NSArray arrayWithObjects: a, b, c, nil]
[array objectAtIndex:i]
[NSDictionary dictionaryWithObjectsAndKeys: v1, k1, v2, k2, nil];
[dictionary valueForKey:k]
@[a, b, c]
array[i]
@{k1:v1, k2:v2}
dictionary[k]
Эта часть новая. Выражение Литералы
Когда у вас есть выражение (M_PI / 16
например) вы должны поместить это в круглые скобки.
Этот синтаксис работает для числовых выражений, логических выражений, поиска индекса в строке (C-), логических значений, констант enum и даже символьных строк!
NSNumber *piOverSixteen = [NSNumber numberWithDouble: (M_PI / 16)];
NSNumber *hexDigit = [NSNumber numberWithChar:"0123456789ABCDEF"[i % 16]];
NSNumber *usesScreenFonts = [NSNumber numberWithBool:[NSLayoutManager usesScreenFonts]];
NSNumber *writingDirection = [NSNumber numberWithInt:NSWritingDirectionLeftToRight];
NSNumber *path = [NSString stringWithUTF8String: getenv("PATH")];
NSNumber *piOverSixteen = @( M_PI / 16 );
NSNumber *hexDigit = @( "0123456789ABCDEF"[i % 16] );
NSNumber *usesScreenFonts = @( [NSLayoutManager usesScreenFonts] );
NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );
NSNumber *path = @( getenv("PATH") );
Подробнее о символьных строках и о том, как / когда вы можете использовать этот буквальный синтаксис:
NSString *path = [NSString stringWithUTF8String: getenv("PATH")];
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
// search for a file in dir...
}
NSString *path = @( getenv("PATH") );
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
// search for a file in dir...
}
Как работают массивы литералов
// when you write this:
array = @[a, b, c ];
// compiler generates:
id objects[] = { a, b, c };
NSUInteger count = sizeof(objects) / sizeof(id);
array = [NSArray arrayWithObjects:objects count:count];
Как работают словарные литералы
// when you write this:
dict = @{k1 : o1, k2 : o2, k3 : o3 };
// compiler generates:
id objects[] = { o1, o2, o3 };
id keys[] = { k1, k2, k3 };
NSUInteger count = sizeof(objects) / sizeof(id);
dict = [NSDictionary dictionaryWithObjects:objects
forKeys:keys
count:count];
Подробнее о подписке на массив
@implementation SongList {
NSMutableArray *_songs;
}
- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
Song *oldSong = [_songs objectAtIndex:idx];
[_songs replaceObjectAtindex:idx withObject:newSong];
return oldSong;
}
@implementation SongList {
NSMutableArray *_songs;
}
- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
Song *oldSong = _songs[idx];
_songs[idx] = newSong;
return oldSong;
}
Подробнее о подписке на словарь
@implementation Database {
NSMutableDictionary *_storage;
}
- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
id oldObject = [_storage objectForKey:key];
[_storage setObject:object forKey:key];
return oldObject;
}
@implementation Database {
NSMutableDictionary *_storage;
}
- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
id oldObject = _storage[key];
_storage[key] = newObject;
return oldObject;
}
[Редактировать 3]
У Майка Эша есть отличная рецензия на эти новые литералы. Если вы хотите узнать больше об этом материале, не забудьте проверить это.
Компилятор Objective-C обладает жестко запрограммированным знанием структуры памяти экземпляров NSConstantString
класс, он же __CFConstantString
учебный класс. Проверьте RewriteObjCStringLiteral
функция в lib/Rewrite/RewriteModernObjC.cpp
в исходном коде лязга. Компилятор просто выдает данные, которые соответствуют расположению экземпляров NSConstantString
учебный класс.
Есть несколько возможностей для буквального NSArray
а также NSDictionary
экземпляров. Они могут сделать что-то вроде того, что они сделали для литеральных строк - жестко закодировать макет экземпляра (для специального подкласса) в компиляторе и выдать данные в этом макете. Или у них может быть код компилятора, который просто создает экземпляр во время выполнения.
1) NSNumber
, NSDictionary
а также NSArray
Литералы доступны в Xcode 4.4.
2) NSDictionary
а также NSArray
для подписки требуется " Xcode 4.4 и OS X 10.8 или более поздняя версия SDK " или " Xcode 4.5 и iOS 6 или более поздняя версия SDK "
Похоже, подписчик нуждается в поддержке во время выполнения и, следовательно, не будет работать до iOS6.
В Apple LLVM Compiler 4.0 добавлена буквальная поддержка Objective-C. Это начинается с
at sign
@
Литералы NSNumber
NSNumber *someBool = [NSNumber numberWithBool:YES];
//BOOL literal
NSNumber *someBool = @YES;
NSNumber *someChar= [NSNumber numberWithChar:'a'];
//character literal
NSNumber *someChar = @'a';
NSNumber *someInt = [NSNumber numberWithInt:1];
NSNumber *someInt = [NSNumber numberWithUnsignedInt:1U];
NSNumber *someInt = [NSNumber numberWithLong:1L];
NSNumber *someInt = [NSNumber numberWithLongLong:1LL];
//integer literal
NSNumber *someInt = @1;
NSNumber *someInt = @1U;
NSNumber *someInt = @1L;
NSNumber *someInt = @1LL;
NSNumber *someFloat = [NSNumber numberWithFloat:3.141592654F];
NSNumber *someFloat = [NSNumber numberWithDouble:3.1415926535];
//float literal
NSNumber *someFloat = @3.141592654F;
NSNumber *someFloat = @3.1415926535;
Литералы коллекции
NSArray *someArray = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];
//array literal
NSArray *someArray = @[ @"A", @"B", @"C" ];
NSDictionary *someDict = [NSDictionary dictionaryWithObjectsAndKeys:
@"key1", @"value1",
@"key1", @"value2",
nil];
//dictionary literal
NSDictionary *someDict = @{ @"Character" : @"Zelda",
@"key1" : @"value2",
@"key2" : @value2 };
Подписка на коллекцию
NSString *var1 = [someArray objectAtIndex:0]; // Returns 'A'
NSString *var2 = [someDict objectForKey:@"key1"]; // Returns 'value1'
//Collection Subscripting
//read
NSString *var1 = someArray[0]; // Returns 'A'
NSString *var2 = someDict[@"key1"]; // Returns 'value1'
//write to mutable collection
someArray[0] = @"AA";
someDict[@"key1"] = @"value11";
Коробочные выражения - выражение в стиле C в Objective-C. Работает с числами, перечислениями, структурами
//Syntax @( <expression> )
[NSNumber numberWithInt:(INT_MAX + 1)];
//Boxed Expressions
NSNumber *var = @(INT_MAX + 1);