objective-c - 为什么不需要取消引用 NSString 指针?

标签 objective-c c nsstring

在例子中

NSString *message = @"Hello";
message = @"World";

如果消息只是一个指针,为什么我不需要像在 C 中那样显式地说明消息中的内容现在等于字符串或 *message = @"World";

最佳答案

免责声明

下面的讨论给出了一个关于为什么你从不取消引用指向 Objective-C 中的对象的指针的一般概念。 然而,关于 NSString 字面量的具体情况,这并不是现实中发生的事情。虽然下面描述的结构仍然是合理的并且它可能以这种方式工作,但实际发生的是字符串文字的空间是在编译时分配的,并且您得到它的地址。这对于字符串文字来说是正确的,因为它们是不可变的和常量的。因此,为了提高效率,每个文字只分配一次。

事实上

NSString * a = @"Hello";
NSString * b = @"Hello";
NSLog(@"%@ %p", a, a); // Hello 0x1f4958
NSLog(@"%@ %p", b, b); // Hello 0x1f4958

原始答案

因为会被翻译成

message = [[NSString alloc] initWithUTF8String:"Hello"]];

这将归结为

message = objc_msgSend(objc_msgSend(objc_getClass("NSString"), @selector(alloc)), @selector(initWithUTF8String:), "Hello");

现在,如果我们看一下 objc_msgSend

的签名
id objc_msgSend(id theReceiver, SEL theSelector, ...)

我们看到该方法返回一个 id 类型,在 Objective-C 中是对象类型。但是 id 实际上是如何定义的呢?

typedef struct objc_object {
    Class isa;
} *id;

id 被定义为指向 objc_object 结构的指针。

所以最后 @"string" 将转换为一个函数调用,该函数调用将生成一个指向对象的指针(即 objc_object 结构,如果您愿意的话),这正是您需要分配给 message 的内容。

最重要的是,您分配的是指针,而不是对象

为了更好地阐明最后一个概念,考虑这个

NSMutableString * a = [NSMutableString stringWithString:@"hello"];
NSMutableString * b = a;
[a setString:@"hola"];
NSLog(@"%@", a); // "hola"
NSLog(@"%@", b); // "hola"

如果您正在分配对象,b 将是 a 的副本,并且 a 的任何进一步修改都不会影响 b.

相反,您得到的是 ab,它们是指向堆中同一对象的两个指针。

关于objective-c - 为什么不需要取消引用 NSString 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15908251/

相关文章:

ios - NSDate 返回不同的答案

ios - 来自initWithString的NSURL对象给出-[NSURL长度]错误

ios - iOS:如何更改字符串中某些字符的颜色/字体

ios - 如何实现占位符文本在 UITextField 中逐字符消失

objective-c - 使用 NSXMLElement 在文本 block 中间添加标签

iphone - 每次应用程序激活时加载 View

c - 代码的系统相关限制

objective-c - 未收到从 iOS 应用程序/MFMailComposeViewController 发送的附件

Apache HTTP : binding an external C library with I/O methods 的自定义模块

余弦泰勒逼近C语言