NSString 文字之间的区别

发布于 2024-12-14 04:27:02 字数 156 浏览 0 评论 0原文

这两行有什么区别?

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

What is the difference between these two lines?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鹿! 2024-12-21 04:27:03

只要记住这个基本的事情:-

NSString *string = ...

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

因此,语句:NSString *string = @"Hello";@"Hello"对象的地址分配给指针字符串。

@"Hello" 被编译器解释为常​​量字符串,编译器自己为其分配内存。

类似地,该语句

NSObject *myObject = somethingElse;

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

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

Just remember this basic thing:-

NSString *string = ...

This is a pointer to an object, "not an object"!

Therefore, the statement: NSString *string = @"Hello"; assigns the address of @"Hello" object to the pointer string.

@"Hello" is interpreted as a constant string by the compiler and the compiler itself allocates the memory for it.

Similarly, the statment

NSObject *myObject = somethingElse;

assigns the address of somethingElse to pointer myObject, and that somethingElse should already be allocated ad initialised.

Therefore, the statement: NSObject *myObject = [[NSObject alloc] init]; allocates and initializes a NSObject object and assigns its address to myObject.

扎心 2024-12-21 04:27:02

@“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)

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

根据上面的文档参考,自动释放没有影响。您可以释放它们,但它们永远不会被释放。因此,它们相等并不是因为两者都是自动释放的字符串,而是因为它们都是常量并且释放被忽略。

@"My String" is a literal string compiled into the binary. When loaded, it has a place in memory. The first line declares a variable that points to that point in memory.

From the string programming guide:

The simplest way to create a string object in source code is to use
the Objective-C @"..." construct:

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

Note that, when creating a string
constant in this fashion, you should avoid using anything but 7-bit
ASCII characters. Such an object is created at compile time and exists
throughout your program’s execution. The compiler makes such object
constants unique on a per-module basis, and they’re never deallocated,
though you can retain and release them as you do any other object.

The second line allocates a string by taking that literal string. Note that both @"My String" literal strings are the same. To prove this:

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);

Outputs the same memory address:

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)

What's telling is not only are the first two string the same memory address, but if you don't change the code, it's the same memory address every time you run it. It's the same binary offset in memory. But, not only is the copy different but it's different every time you run it since it's allocated on the heap.

The autorelease has no affect according to the doc ref above. You can release them but they are never deallocated. So, they are equal not because both are autoreleased string but that they're both constants and the release is ignored.

梦纸 2024-12-21 04:27:02

一种是文字字符串,它在执行应用程序的生命周期中持续存在。另一个可能是一个动态对象,仅持续到自动释放为止。 (如果系统决定以这种方式优化它,它也可能是一个文字字符串——不能保证它不会。)

One is a literal string, which persists for the life of the executing app. The other may be a dynamic object that only persists until autoreleased. (It may also be a literal string, if the system decides to optimize it that way -- there are no guarantees it won't.)

又怨 2024-12-21 04:27:02

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

bryanmac is 100% correct in his answer. I just added an explicit example using GHUnit.

NSString creation - literal vs nonliteral.

Shows strings created in various ways if they are literal nor nonliteral.

- (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);
}
白鸥掠海 2024-12-21 04:27:02

它们之间没有区别。您在第一个示例中显示的启动方式的字符串是自动释放的字符串。

There is no difference between them. A string initiated how you showed in the first example is an autoreleased string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文