【问题标题】:Setting an immutable object equal to something将不可变对象设置为等于某物
【发布时间】:2013-12-30 17:44:28
【问题描述】:

Label有一个属性调用AttributeText,

@property (nonatomic, strong) NSAttributedString *attributedText;

这个属性字符串是不可变的。所以要修改它,你必须制作一个可变副本。

NSMutableAttributedString *labelText= [myLabel.attributedText mutableCopy];
[labelText setAttributes:...];
myLabel.attributedText = labelText;

请哪位大神解释一下在这个过程中记忆中的幕后发生了什么。

myLabel.attributedText 是一个指针,指向内存中的一个属性文本对象,该对象已经被分配和初始化。

接下来,您将复制该对象并将 *labelText 设置为指向内存中的该对象。

所以你接下来使用 setAttributes 方法修改 labelText 指向的对象。

但是最后一行发生了什么?我们只是将 myLabel.attributedText 设置为指向 labelText 在内存中指向的同一对象吗?

如果是这样,一旦整个事情超出范围,*labelText 将设置为 nil,但它指向的对象仍保留在内存中,因为 myLabel.attributedText 仍然指向它,保持保留计数为 1。

ARC 是否只是自动释放 myLabel.attributedText 最初指向的旧对象?

人们是如何在 ARC 之前发布该对象的?

当函数超出范围时,ARC 是否总是知道将 labelText 指针设置为 nil?

那么在对象超出范围时保持对象存活的方法是设置一个具有强指针的属性以指向该对象?超出范围时,本地指针是否总是设置为零?

编辑:我也没有注意到您将 NSattributedString 指针设置为指向 NSMutableAttributedString 对象。斯坦福演讲笔记有一个错字。如果你确实在你的代码中犯了这个错误,它仍然可以编译和运行吗?

【问题讨论】:

  • 在 ARC 之前,您并不关心存储在属性中的对象。您只需要关心您使用mutableCopy 分配的实例并且必须释放此所有权。最后加上[labelText release]
  • 了解对象和指向对象的指针之间的区别非常关键。听起来您快到了,但还没有完全掌握。
  • Hot Licks,你知道有什么资源可以帮助我了解更多吗?我想了解幕后发生的所有微妙之处,但不幸的是,大多数讲座从未解释过。现在感觉就像我知道的足够危险。
  • 恐怕我手上的书都是30-40岁。但是一个好的讲师会在这个概念上花几节课,然后再回来几次,以明确其意义。 (它实际上可能有助于学习机器/汇编语言,以了解您在高级语言中看到的东西“下面”是什么。)

标签: ios objective-c automatic-ref-counting


【解决方案1】:

由于属性是用strong修饰符定义的,这意味着在赋值时,系统会保留分配的labelText,所以一旦方法返回就不会释放。

请记住,对象是在堆上分配的,因此它们不受超出范围的方法的影响。使用 ARC,未使用的对象会自动为您释放。由于您示例中的属性为strong,因此该对象被保留,系统不会释放它。

这适用于可变对象,因为NSMutableAttributedString 继承自NSAttributedString(它是一个子类)。在此处阅读更多信息:Polymorphism

请务必注意,attributedText 的定义与您的代码示例中的不同:

@property(nonatomic,copy) NSAttributedString *attributedText

注意这里的修饰符是copy,而不是retain

实际发生的情况是可变对象将复制到另一个实例,该实例将由标签保留,而您的可变属性字符串将在分配后立即释放。

使用copy 代替strong 以确保设置attributedText 时传递的值保持不变。

【讨论】:

  • strongcopy 之间的区别在这种情况下并不那么重要,因为内存语义是相同的。
  • 我试图更多地了解编译器如何处理指针和实际对象。让我们假设在第一个示例中,myLabel.attributedText 很强大,我是否正确地说当函数超出范围时,将有 2 个指针指向属性字符串对象?本地指针labelText不会被释放?在属性复制的第二个示例中,当您将 myLabel.attributedText 设置为指向它时,您正在制作属性字符串的副本(最初也是副本)?
  • @iMartin 是的,我只是在copy 上添加了注释来进一步解释。
  • 另外,在最后一行,如果我们只是将 myLabel.attributedText 设置为指向一个属性字符串对象。这是如何运作的?因为这个对象是可变的。您正在设置一个不可变指针以指向一个可变对象。这就是属性是复制而不是强的原因吗?
  • 哇,非常感谢您的帮助。像这样的细节太多了,视频讲座没有涵盖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 2010-12-08
  • 1970-01-01
相关资源
最近更新 更多