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 #import
s 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.
精彩评论