Подтвердить что ты не робот

Понимание линии между Objective-C и Foundation, в частности, NSString

В Objective-C я могу написать:

id pString = @"Hello, World.";

и компилятор будет создавать экземпляр NSString без необходимости прямого вызова метода factory. Однако NSString действительно является только классом Foundation и, следовательно, предположительно не является частью фактического определения языка Objective-C.

Итак, когда я пишу @"String", как компилятор знает, в частности, построить NSString, а не какой-нибудь другой подобный строке объект? Другими словами, где останавливается язык Objective-C и библиотека Foundation?

4b9b3361

Ответ 1

Когда вы пишете Objective-C код вне сред Cocoa или GNUStep, @"..." не связан с NSString.

В этом случае gcc предоставляет параметр для указания класса, связанного с литеральными строками:

-fconstant-строка-класс = имя-класса
Использовать имя класса как имя класса для создания экземпляра для каждого буквальная строка, указанная в синтаксисе "@"..."". По умолчанию имя класса - "NXConstantString".

Ответ 2

Директива @"", по-видимому, встроена в компилятор objective-c.

Например, если вы удалите все #import из вашего исходного файла .m(заголовок префикса), следующая строка будет синтаксической ошибкой:

NSString *string = @"ABCD"; // (Doesn't know anything about NSString class)

Однако, если вы измените тип Foundation NSString на встроенный тип void, он скомпилирует только штраф:

void *string = @"ABCD";

Итак, даже без определения Foundation NSString компилятор знает, как превратить @"" в то, что может стать экземпляром NSString во время выполнения (возможно, он не будет создавать экземпляр без Foundation, но компилятор не выполняет кажется, неважно); Поскольку он принимает синтаксис, не требуя каких-либо определений внешней библиотеки, компилятор видит @"" как часть языка.

Однако ваш код не сможет использовать какой-либо экземпляр @"" без импорта Foundation.h, поэтому с точки зрения вашей программы @"" является частью библиотеки.

Ответ 3

Еще один интересный бит состоит в том, что строковый литерал Objective-C (@"") возвращает тот же тип, что и явно созданный объект NSString:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    printf("string literal class: %s\n", object_getClassName(@"a string literal"););

    NSString *str = [[NSString alloc] initWithUTF8String:"asdf"];
    printf("explicit NSString class: %s", object_getClassName(str));

    [pool drain];
    return 0;
}

Я смутно помню, что в других более старых реализациях Objective-C строковый литерал фактически возвращал объект немного другого класса, но он мог бы использоваться взаимозаменяемо с NSString/NSCFString. Однако не совсем уверен в этой части.