Які деталі "Objective-C Literals" згадані в примітках до випуску Xcode 4.4?


188

Я переглядав нотатки до випуску Xcode 4.4 і помітив це:

Компілятор LLVM 4.0

Тепер Xcode включає Apple LLVM Compiler версії 4.0, включаючи такі нові мовні функціїOOctive-C: [...]
- Літерали Objective-C: створюйте літерали для NSArray, NSDictionary та NSNumber, точно так само, як і літерали для NSString

Мене заінтригує ця особливість. Це не зовсім ясно мені, наскільки в литералов для NSStringроботи і як можна було б використовувати їх NSArray, NSDictionaryі NSNumber.

Які деталі?


Не відповідь, але тут є деякі міркування: reddit.com/r/programming/comments/pso6x/xcode_43_released/…
Арджан Тіммс

3
"Чи не цей матеріал є предметом NDA?" А ваша проблема?
Hejazzman

7
Ні, Apple чітко сказала, що ці доповнення не є NDA у списку розсилки.
griotspeak

2
Про це у LLVM є кілька документів: clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
Стівен Крамер

3
Ось посилання безпосередньо на дискусію "Кланг" з літератури Objective-C: clang.llvm.org/docs/ObjectiveCLiterals.html
ThomasW

Відповіді:


393

Скопійовано дослівно з http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :

Літерали Objective-C: тепер можна створювати літерали для NSArray, NSDictionary і NSNumber (так само, як можна створити літерали для NSString)

NSArray Literals

Раніше:

array = [NSArray arrayWithObjects:a, b, c, nil];

Зараз:

array = @[ a, b, c ];

NSD Dictionary Literals

Раніше:

dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3]
                                   forKeys:@[k1, k2, k3]];

Зараз:

dict = @{ k1 : o1, k2 : o2, k3 : o3 };

NSNumber Literals

Раніше:

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-) рядку, булевих значень, констант перерахунків і навіть рядків символів!

Виразні літерали

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]

Майк Еш чудово пише про ці нові літерали. Якщо ви хочете дізнатися більше про цей матеріал, переконайтесь, що це перевіряють .



9
Я бачу, як це пришвидшило моє кодування!
Педро Манчено

12
Чи є спосіб отримати xCode 4.3 для підтримки цих нових позначень? Я хочу їх - ЗАРАЗ ... але я ТАК не "піднімаюся на гору" для них ...
Алекс Сірий

20
У вас багато текстового вмісту, вбудованого у зображення, які пошуковій системі було б більш досконало, якби він був розміщений як звичайний текст.
Білл Ящірка

5
@BilltheLizard Я з повагою не згоден. Велика частина тесту або не-пошук річ , як {і [, або загальні слова , як array, idі @implementation. Відповідні ключові слова - це literal, objcа xcodeне конкретні згадки про [або @implementation. Ви не хочете, щоб це питання відображалося для загальних запитів ObjC в Google, воно повинно відображатися лише тоді, коли хтось запитує objc literal, що відбувається в даний час (завдяки заголовку та тегам).
Pooria Azimi

4
Тепер це називається відповідь StackOverflow. Гарна робота Pooria.
Нітіш

15

Компілятор Objective-C має жорсткі знання про макет пам'яті екземплярів NSConstantStringкласу, який називається __CFConstantStringкласом. Ознайомтеся з RewriteObjCStringLiteralфункцією у lib/Rewrite/RewriteModernObjC.cppвихідному коді clang. Компілятор просто випромінює дані, які відповідають компонуванню екземплярів NSConstantStringкласу.

Існує пара можливостей для буквальних NSArrayта NSDictionaryекземплярів. Вони могли зробити щось на кшталт того, що вони робили для буквальних рядків - жорсткий код макета екземпляра (для спеціального підкласу) у компіляторі та випромінювати дані в цьому макеті. Або вони могли мати код компілятора, який просто створює екземпляр під час виконання.


2
Реалізація буквеного синтаксису об'єкта для NSArrayта NSDictionaryзовсім несхожа на таку NSString. Компілятор просто просто генерує дзвінок до NSDictionaryабо NSArrayпід час виконання. Ось чому глобальні змінні не можна ініціалізувати за допомогою цього синтаксису (на відміну від цього NSString). Це вимагає, щоб результат був постійною часом компіляції.
Buzzy

1

З «Літератури Objective-C»

1) NSNumber, NSDictionaryі NSArrayлітерали доступні в Xcode 4.4 .

2) NSDictionaryі NSArrayпідписка потребує " Xcode 4.4 та SD X 10.8 або новішої версії SDK " або " Xcode 4.5 та iOS 6 або новішої SDK "

Мені здається, що для підписки потрібна підтримка в режимі виконання, отже, вона не працюватиме до iOS6 .


у цій самій статті йдеться про "Повернення до iOS 4" у колонці "Розгортання iOS"
code007

1
Я випадково використовував літерали масиву в проекті, який я компілював із Xcode 4.5. Вона працює на iPad під керуванням iOS5. Він не компілюється на Xcode 4.2, тому я з’ясував, що я це зробив.
JScarry

Підписка може бути змушена
Стівен Фішер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.