【问题标题】:Do instance references really work in Swift?实例引用在 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这样的参考,那么我的错误是什么?

【问题讨论】:

    标签: objective-c swift reference nsdictionary swift-playground


    【解决方案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:我问了一个关于这个的具体问题:stackoverflow.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 这个答案用几句话说明了问题所在,这是正确的,谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多