NSString文字之间的区别

这两条线有什么区别?

NSString * string = @"My String"; NSString * string = [[[NSString alloc] initWithString:@"MyString"] autorelease] 

@“我的string”是一个编译到二进制文件的文字string。 加载时,它在内存中占有一席之地。 第一行声明一个指向内存中的那个点的variables。

从string编程指南:

在源代码中创buildstring对象最简单的方法是使用Objective-C @“…”结构:

 NSString *temp = @"/tmp/scratch"; 

请注意,以这种方式创buildstring常量时,应避免使用除7位ASCII字符之外的任何内容。 这样的对象是在编译时创build的,并存在于整个程序的执行过程中。 编译器使这样的对象常量在每个模块的基础上是唯一的,并且它们不会被释放,虽然你可以保留和释放它们,就像你做任何其他对象一样。

第二行通过取文字串来分配一个string。 请注意,这两个@“我的string”文字string是相同的。 为了certificate这一点:

 NSString *str = @"My String"; NSLog(@"%@ (%p)", str, str); NSString *str2 = [[NSString alloc] initWithString:@"My String"]; NSLog(@"%@ (%p)", str2, str2); NSString *copy = [str2 stringByAppendingString:@"2"]; NSLog(@"%@ (%p)", copy, copy); 

输出相同的内存地址:

 2011-11-07 07:11:26.172 Craplet[5433:707] My String (0x100002268) 2011-11-07 07:11:26.174 Craplet[5433:707] My String (0x100002268) 2011-11-07 07:11:26.174 Craplet[5433:707] My String2 (0x1003002a0) 

告诉的不仅仅是前两个string是相同的内存地址,但是如果不更改代码,每次运行时都是相同的内存地址。 内存中的二进制偏移量是相同的。 但是,不仅副本不同,而且每次运行它时都会有所不同,因为它是分配在堆上的。

autorelease根据上面的文档ref没有影响。 你可以释放他们,但他们永远不会被释放。 所以,他们是平等的不是因为都是自动释放string,但他们都是常量,释放被忽略。

一个是文字string,它持续执行应用程序的生命。 另一个可能是一个dynamic的对象,只有自动释放才会持续。 (如果系统决定以这种方式进行优化,它也可能是一个文字string – 没有保证它不会。)

bryanmac在他的回答中是100%正确的。 我刚刚添加了一个使用GHUnit的明确例子。

NSString创build – 字面与nonliteral。

显示以各种方式创build的string,如果它们是文字或非文字的。

 - (void) test_stringCreation { NSString *literalString = @"literalString"; NSString *referenced = literalString; NSString *copy = [literalString copy]; NSString *initWithString = [[NSString alloc] initWithString:literalString]; NSString *initWithFormat = [[NSString alloc] initWithFormat:@"%@", literalString]; // Testing that the memory addresses of referenced objects are the same. GHAssertEquals(literalString, @"literalString", @"literal"); GHAssertEquals(referenced, @"literalString", @"literal"); GHAssertEquals(copy, @"literalString", @"literal"); GHAssertEquals(initWithString, @"literalString", @"literal"); GHAssertNotEquals(initWithFormat, @"literalString", @"nonliteral - referenced objects' memory addresses are \ different."); // Testing that the objects referenced are equal, ie isEqual: . GHAssertEqualObjects(literalString, @"literalString", nil); GHAssertEqualObjects(referenced, @"literalString", nil); GHAssertEqualObjects(copy, @"literalString", nil); GHAssertEqualObjects(initWithString, @"literalString", nil); GHAssertEqualObjects(initWithFormat, @"literalString", nil); // Testing that the strings referenced are the same, ie isEqualToString: . GHAssertEqualStrings(literalString, @"literalString", nil); GHAssertEqualStrings(referenced, @"literalString", nil); GHAssertEqualStrings(copy, @"literalString", nil); GHAssertEqualStrings(initWithString, @"literalString", nil); GHAssertEqualStrings(initWithFormat, @"literalString", nil); } 

他们之间没有区别。 一个string启动了你在第一个例子中显示的是一个自动释放的string。

只要记住这个基本的东西:

 NSString *string = ... 

这是一个指向一个对象的指针,“不是一个对象”!

因此,声明: NSString *string = @"Hello";@"Hello"对象的地址赋给指针string。

@"Hello"被编译器解释为一个常量string,编译器本身为它分配内存。

同样,这个说法

 NSObject *myObject = somethingElse; 

将somethingElse的地址分配给myObject指针,并且应该已经分配和初始化了somethingElse

因此,声明: NSObject *myObject = [[NSObject alloc] init]; 分配和初始化一个NSObject对象,并将其地址分配给myObject