这两行之间有什么区别?
NSString * string = @"My String";
NSString * string = [[[NSString alloc] initWithString:@"MyString"] autorelease]
答案 0 :(得分:23)
@“My String”是编译成二进制文件的文字字符串。加载后,它在内存中占有一席之地。第一行声明一个指向内存中该点的变量。
来自字符串编程指南:
在源代码中创建字符串对象的最简单方法是使用 Objective-C @“...”构造:
NSString *temp = @"/tmp/scratch";
注意,创建字符串时 以这种方式保持不变,除了7位之外,你应该避免使用任何东西 ASCII字符。这样的对象是在编译时创建的并且存在 整个程序执行期间。编译器生成这样的对象 每个模块唯一的常量,它们永远不会被释放, 虽然你可以保留和释放它们,就像你做任何其他对象一样。
第二行通过获取该文字字符串来分配字符串。请注意,@“My String”文字字符串都是相同的。为了证明这一点:
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)
告诉我们不仅前两个字符串是相同的内存地址,而且如果不更改代码,每次运行它时都是相同的内存地址。它与内存中的二进制偏移量相同。但是,不仅副本不同,而且每次运行它都会有所不同,因为它是在堆上分配的。
根据上面的doc ref,自动释放没有任何影响。您可以释放它们,但它们永远不会被释放。所以,它们是相同的,不是因为它们都是自动释放的字符串,而是它们都是常量而且发布被忽略。
答案 1 :(得分:6)
一个是文字字符串,它在执行应用程序的生命周期中持续存在。另一个 可能 是一个动态对象,只有在自动释放后才会持续存在。 (它也可能是一个文字字符串,如果系统决定以这种方式优化它 - 不能保证它不会。)
答案 2 :(得分:2)
bryanmac在答案中100%正确。我刚刚使用GHUnit添加了一个明确的示例。
NSString
创作 - 文字与非文字。显示以各种方式创建的字符串,如果它们是文字的,也不是非文字的。
- (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, i.e. 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, i.e. isEqualToString: .
GHAssertEqualStrings(literalString, @"literalString", nil);
GHAssertEqualStrings(referenced, @"literalString", nil);
GHAssertEqualStrings(copy, @"literalString", nil);
GHAssertEqualStrings(initWithString, @"literalString", nil);
GHAssertEqualStrings(initWithFormat, @"literalString", nil);
}
答案 3 :(得分:1)
它们之间没有区别。在第一个示例中显示的字符串是一个自动释放的字符串。
答案 4 :(得分:0)
记住这个基本的东西: -
NSString *string = ...
这是指向对象的指针,"不是对象"!
因此,语句:NSString *string = @"Hello";
将@"Hello"
对象的地址分配给指针字符串。
@"Hello"
解释为常量字符串,编译器本身为其分配内存。
同样,声明
NSObject *myObject = somethingElse;
将somethingElse的地址分配给指针myObject
,并且somethingElse
应该已经分配了广告初始化。
因此,声明:NSObject *myObject = [[NSObject alloc] init];
分配并初始化NSObject
对象,并将其地址分配给myObject
。