Понимание границы между Objective-C и Foundation, в частности, NSString - PullRequest
11 голосов
/ 15 февраля 2010

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

id pString = @"Hello, World.";

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

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

Ответы [ 3 ]

6 голосов
/ 15 февраля 2010

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

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

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

3 голосов
/ 15 февраля 2010

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

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

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

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

void *string = @"ABCD";

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

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

0 голосов
/ 15 февраля 2010

Еще один интересный момент заключается в том, что строковый литерал 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. Впрочем, не совсем уверен в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...