开发者

Understanding the line between Objective-C and Foundation, specifically NSString

In Objective-C, I can write:

id pString = @"Hello, World.";

and the compiler will instantiate an NSString without me needing to explicitly call a factory method. However, NSString is really just a Foundation class and thus presumably not part of the actual Objective-C language definition.

So when I write @开发者_开发技巧"String", how does the compiler know to build an NSString in particular, and not some other string-like object? In other words, where does the Objective-C language stop and the Foundation library start?


When you write Objective-C code outside of Cocoa or GNUStep environments, @"..." is not linked to NSString.

In this case, gcc provides an option for specifying a class associated to literal strings:

-fconstant-string-class=class-name
Use class-name as the name of the class to instantiate for each literal string specified with the syntax "@"..."". The default class name is "NXConstantString".


The @"" directive appears to be built-in to the objective-c compiler.

For instance, if you remove all #imports from your .m source file (& prefix header), the following line will be a syntax error:

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

However, if you change the Foundation NSString type to the built-in void type, it will compile just fine:

void *string = @"ABCD";

So, even without Foundation's NSString definition, the compiler knows how to turn @"" into something that can become an NSString instance at runtime (it probably won't instantiate without Foundation, but the compiler doesn't seem to mind); Since it accepts the syntax without needing any external library definitions, the compiler sees @"" as part of the language.

Your code, however, won't be able to make use of any @"" instance without importing Foundation.h, so from the point of view of your program, @"" is part of the library.


Another interesting bit is that an Objective-C string literal (@"" notation) returns the same type as an explicitly instantiated NSString object:

#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;
}

I vaguely remember that in other, older implementations of Objective-C, the string literal actually returned an object of a slightly different class, but that could be used interchangeably with NSString/NSCFString. Not totally sure on that part, though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜