Objective-C NSString 引用类型

Posted

技术标签:

【中文标题】Objective-C NSString 引用类型【英文标题】:Objective-C NSString Reference Types 【发布时间】:2016-05-13 03:14:36 【问题描述】:

我有一个简单的问题。如果我声明 NSString (ref type) 如下所示:

 NSString *johnsMoney = @"200";
    NSString *marysMoney = johnsMoney;

    NSLog(@"Johns Money %@",johnsMoney);
    NSLog(@"Marys Money %@",marysMoney);

    johnsMoney = @"100";
    NSLog(@"Johns Money %@",johnsMoney);
    NSLog(@"Marys Money %@",marysMoney);

产生的输出是这样的:

 Johns Money 200
 Marys Money 200
 Johns Money 100
 Marys Money 200

根据我的理解,当我将 @"100" 分配给 johnsMoney 时,它是否也不会将“marysMoney”的值更改为 100,因为 marysMoney 指向 johnsMoney。

更新:

我相信以下示例显示了我最初尝试做的事情:

Dog *dog1 = [[Dog alloc] init];
dog1.name = @"Dog 1";

Dog *dog2 = dog1;

NSLog(@"Dog 1 %@",dog1.name);
NSLog(@"Dog 2 %@",dog2.name);

dog1.name = @"Dog 3";

NSLog(@"Dog 1 %@",dog1.name);
NSLog(@"Dog 2 %@",dog2.name);

【问题讨论】:

***.com/a/16460928 我猜这个答案将消除疑问。 【参考方案1】:

johnsMoneymarysMoney 都是pointers to strings

当您编写johnsMoney = @"100" 时,它现在指向不同的字符串。这不会改变仍然指向原始字符串的marysMoney

如果您使用NSMutableString,而您使用了[johnsMoney setString:@"100"],那么它会更改基础数据(两个变量仍将指向该数据)。

【讨论】:

【参考方案2】:

它们不是参考。它们是对象指针。如果两个变量恰好指向同一个对象,将一个指针更改为指向另一个对象对另一个指针没有影响。

想想两个人站得很近。两人都伸出一只手臂,指向同一张桌子。现在一个人转身指着一把椅子。另一个人不受影响。他们仍然指着桌子。

【讨论】:

对象指针引用。他们只是碰巧彼此独立。【参考方案3】:

没有。请记住,您正在处理指针。所以当你这样做时

johnsMoney = @"100";

您正在将johnsMoney 指针设置为包含@"100" 值的不同内存地址。 marysMoney 仍然指向具有 @"200" 值的原始地址。

【讨论】:

【参考方案4】:

在您的示例中,局部变量 marysMoney 保持对初始 johnsMoney 对象的强引用。当johnsMoney 属性发生变化时,该属性不再保持对原始值的强引用,但该值仍由marysMoney 强变量保持活动状态。

【讨论】:

【参考方案5】:

@"200" 是 NSString 对象的objective-c 表示法。它将拥有自己的内存空间,johnsmoney 将指向它。所以,marysmoney 从来没有真正指向 johnsmoney。

实际发生的事情是这样的......

Johns Money 200 // pointer 1
Marys Money 200 // pointer 1
Johns Money 100 // pointer 2
Marys Money 200 // pointer 1

johnsmoney 指向@"200"。 marysmoney 也指向@"200"。当 johnsmoney 被分配@"100" 时,johnsmoney 指向@"100"。虽然 marysmoney 仍然指向 @"200"。

【讨论】:

【参考方案6】:

假设字符串: @"200" 指针地址:0xeeff @"100" 指针地址:0xeeaa

所以,你的代码可能会改变如下:

 NSString *johnsMoney = @"200";
(johnsMoney = 0xeeff)
 NSString *marysMoney = johnsMoney;
(marysMoney = 0xeeff)

 johnsMoney = @"100";
(johnsMoney = 0xeeaa)
(marysMoney = 0xeeff) 

marysMoney 指针地址没有改变,但是 johnsMoney 指针地址改变了。

同样: 假设对象: dog1 指针地址:0xeeff

所以,你的代码可能会改变如下:

Dog *dog1 = [[Dog alloc] init];
(dog1 pointer address: 0xeeff)

dog1.name = @"Dog 1";

Dog *dog2 = dog1;
(dog2 pointer address: 0xeeff)

dog1.name = @"Dog 3";
(dog1 pointer address still: 0xeeff)
(dog2 pointer address still: 0xeeff)

因为它们都指向同一个地址,所以它们都改变了。

【讨论】:

【参考方案7】:

简单地说。

NSString *johnsMoney = @"200";
//here johnsMoney is declared as NSString, so it will be string type.
//any thing given inside @"" will be considered as string.
//currently, johnsMoney contains 200.

NSString *marysMoney = johnsMoney;
//here marysMoney is declared as NSString, so it will be string type.
//johnsMoney is already a string. therefore, marysMoney automatically reads the
//string in johnsMoney. so currently, marysMoney will also be 200.

NSLog(@"Johns Money %@",johnsMoney);
NSLog(@"Marys Money %@",marysMoney);
//both will be printed as 200. right?

johnsMoney = @"100";
//now johnsMoney reassigned as 100.
//but still marysMoney is 200.
//there is nothing written for changing maryMoney from 200.

NSLog(@"Johns Money %@",johnsMoney);
NSLog(@"Marys Money %@",marysMoney);

所以我想你已经明白了。我不想通过包含指针来以复杂的方式思考它。

Note:if any one feels that it is rubbish, kindly please avoid my answer. am sorry to post it. i just only vomited the pointer concept. i don't know how much correct is my answer.

【讨论】:

【参考方案8】:

NSString 是值类型。 (不可变)。

还有sting iterning 的概念。

NSString *johnsMoney = @"200";
NSString *marysMoney = johnsMoney;
johnsMoney = @"100";

因此,当您更改 johnsMoney 字符串时,它现在指向新的内存地址。但是 marysMoney 仍然有旧的刺痛(即 200)所以指向以前的地址。

阅读本教程,您将学到很多新东西。 https://nshipster.com/equality/

【讨论】:

以上是关于Objective-C NSString 引用类型的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C 对象是按值传递还是按引用传递?

Objective-C 中的 NSString 标记化

来自 NSString 的 Objective-C 标识符

objective-c block

正确填充 NSString 的 Objective-c 代码?

Objective-C KVC 自己主动转换类型研究