实例引用在 Swift 中真的有效吗?

Posted

技术标签:

【中文标题】实例引用在 Swift 中真的有效吗?【英文标题】:Do instance references really work in Swift? 【发布时间】:2015-09-17 09:02:09 【问题描述】:

我先写了 Objective-C 代码

NSMutableString *aStrValue = [NSMutableString stringWithString:@"Hello"];
NSMutableDictionary *aMutDict = [NSMutableDictionary dictionary];
[aMutDict setObject:aStrValue forKey:@"name"];

NSLog(@"Before %@",aMutDict);
[aStrValue appendString:@" World"];
NSLog(@"After %@",aMutDict);

我得到如下输出

2015-09-17 14:27:21.052 ShareIt[4946:129853] Before 
    name = Hello;

2015-09-17 14:27:21.057 ShareIt[4946:129853] After 
    name = "Hello World";

意味着当我将一个字符串附加到一个实际引用到 MutableDictionary 的可变字符串时,更改也会反映在 Dictionary 中..

但后来我在 Swift 中尝试了相同的方法

var stringValue:String?
stringValue = "Hello"

var dict:Dictionary = ["name":stringValue!]
println(dict)
stringValue! += " World"
stringValue!.extend(" !!!!")
println(dict)

我在操场上看到这样的输出

我的问题是

为什么改变的值没有反映在像这样的数据结构中 字典。 在 Swift 中添加任何键值是否真的会保留该值或其 参考,如果它保持像objective-C这样的参考,那么我的错误是什么?

【问题讨论】:

【参考方案1】:

参考类型

不同的行为取决于您在 Objective-C 代码中使用NSMutableString 的事实,即class。 这意味着aMutDictaStrValueNSMutableString 类型的同一对象的引用。因此,您使用 aStrValue 应用的更改对 aMutDict 可见。

值类型

另一方面,在 Swift 中,您使用的是 String struct。这是一个值类型。这意味着当您将值从一个变量复制到另一个变量时,您使用第一个变量所做的更改对第二个变量不可见。

以下示例清楚地描述了value type 行为:

var word0 = "Hello"
var word1 = word0

word0 += " world" // this will NOT impact word1

word0 // "Hello world"
word1 // "Hello"

希望这会有所帮助。

【讨论】:

@user2864740:怎么样? appzYourLife 的回答绝对正确。 @user2864740:两个示例(Objective-CSwift)都在可变上下文中。事实上,OP 使用NSMutableStringNSMutableDictionaryvar Stringvar Dictionary(全部为mutables)。这里真正的区别在于NSMutableString 是一个对象(引用类型),而String 是一个结构(值类型)。所以这里我们讨论的是reference typesvalue types不是可变性 还有一件事——在 ObjC 中,只有 NSMutableString 被作为引用类型传递,另一方面 NSString 的行为类似于值类型。那是因为string interning 的原因——马特告诉我here @user2864740:我问了一个关于这个的具体问题:***.com/questions/32638879/… @appzYourLife 啊,me too(从不同的角度)。非常有趣的学习新东西 - 即。我认为地址会在没有中间操作的情况下被固定。【参考方案2】:

Swift 中的字符串(按值复制)与 Objective C 中的字符串(按引用复制)完全不同。

来自 Apple 的 Swift 文档:

字符串是值类型

Swift 的 String 类型是一个值类型。如果您创建一个新的字符串值, 该字符串值在传递给函数或方法时被复制, 或者当它被分配给一个常量或变量时。在每种情况下,一个新的 创建现有 String 值的副本,新副本为 通过或分配,而不是原始版本。值类型是 结构和枚举中描述的值类型。

Swift 的默认复制字符串行为确保当一个函数 or 方法传递给你一个字符串值,很明显你拥有它 确切的字符串值,无论它来自何处。你可以 确信您传递的字符串不会被修改,除非 你自己修改。

在幕后,Swift 的编译器优化了字符串的使用,以便 只有在绝对必要时才会进行实际复制。这表示 使用字符串作为值时,您总是会获得出色的性能 类型。

【讨论】:

【参考方案3】:

在 swift 中,String 是一个 Struct。 结构不是 Swift 中的引用类型,因此当您将其设置为字典时会复制它。

【讨论】:

@user2864740: Strings in Swift are structs,不是引用类型。 @user2864740:那么请提供答案。到目前为止,您只是不同意人们的观点,并没有提供任何有用的数据。 @user2864740 这个答案用几句话说明了问题所在,这是正确的,谢谢

以上是关于实例引用在 Swift 中真的有效吗?的主要内容,如果未能解决你的问题,请参考以下文章

为分发而创建的 swift 框架中的绝对路径引用

如何在 Swift 子类中引用目标 c 实例变量?

Swift学习笔记-自动引用计数弱引用和无主引用

Swift学习笔记-自动引用计数弱引用和无主引用

引用实例方法需要等效性 (SWIFT)

swift 学习之自动引用计数