objective-c - 从 C 程序员的角度来看,在 Objective C 中保留对象

标签 objective-c cocoa pointers

我已经用 C 编程了 15 年以上,最近开始使用 Objective C,但有一件事我不太明白:有几个方法返回一个指向对象的指针,但我不拥有这个对象。相反,人们说只要我需要访问这个对象,我就需要保留它。

我们以[NSTextField stringValue]的返回值为例。这个方法将返回一个 NSString 给我。但我不拥有这个 NSString,所以如果我想使用它,我就必须在需要时保留它,例如

NSString *s = [myTextField stringValue];
...              // why can't the object become invalid during this time?
[s retain];  
....             // do some work
[s release];

这里真正让我困惑的是调用 [myTextField stringValue] 和 [s keep] 之间的时间。我不拥有 NSString,那么当我在上面代码的第三行中执行保留调用时,谁保证指向 NSString 的指针仍然有效?

上面的代码当然很简单,但是既然要保证调用retain时“s”指针仍然有效,那不是也得保证调用retain时指针仍然有效吗很久以后才在弦上?假设调用 [NSTextField stringValue] 4 小时后?我的意思是,我什至可以将 NSString 指针存储在全局变量中,并在很久以后对其调用保留,或者是否有一条规则,保留必须在当前范围内发生,或者在获取指针后不久而不是 4 小时后发生?尽管如此,还是很难理解 Objective C 编译器/运行时应该如何跟踪所有这些。

从 C 程序员的角度来看,上面的代码中的保留似乎有点多余,因为如果可以对其调用 [retain],[NSTextField stringValue] 返回的指针无论如何都必须保持有效。但事实当然不可能如此。我相信一旦你明白了这个想法,这一切都是有道理的,但目前我仍在努力理解这一点,因为它与我多年来在 C 中所做的事情相矛盾。

希望有人能对此有所启发。谢谢!

最佳答案

嗯,我相信您知道保留和释放已被弃用,并且有了 ARC,我们不再需要为这些东西增加负担。

在您的示例中,您正在创建一个新指针: NSString *s 并将其指定为指向文本字段及其文本属性所指向的同一地址。重要的是要理解 s 的范围仅限于此处的这段特定代码,该代码由一些花括号(大括号)包围。如果你在 s 上调用保留,你也必须在这个范围内释放它,因为之后你不再拥有 s 指针,并且会发生泄漏。 但是 s 指向的对象无论如何都会一直保留到该作用域的末尾,因此这个保留/释放对是多余的。

如果您确实想在将来某个不确定的时刻使用此字符串,那么您的指针需要将范围限制为整个实例,无论是作为属性还是 iVar。然后,您可以根据您的示例调用保留,并保存释放它,直到将来的某个时间,如果 textField 被释放,则其 NSString *text 属性指向的 NSString 对象应该存活,因为当 textField 对其引用调用释放时计数没有达到零;您之前在保留中添加了一个。因此,保留可能被认为是“购买此对象的份额”,而释放则被认为是“出售我在该对象中的份额”。对象本身决定比来自 textField 的释放消息更长寿,当时 textField 只是其所有者之一。

综上所述,在当时制作自己的字符串副本将是一种更为传统的方法,并且如果您只是在属于该对象的对象上添加保留,那么许多程序员将是至关重要的用户界面(或任何东西)。这种巫术的最大陷阱是,您可以轻松地创建一个“保留循环”——一个所有权循环,它只能涉及两个对象,但也可能很容易成为一个复杂的图。保留周期可能很难追踪,因此最好通过良好的设计来避免它们。

关于objective-c - 从 C 程序员的角度来看,在 Objective C 中保留对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29490072/

相关文章:

c - 初始化并打印 const char 指针

ios - 在 Swift 中使用 commitEditingStyle 动态删除 UITable 部分

ios - 在 MMDrawerController 之上放置一个 View

macos - 显示 Mac OS X 系统 NSMenu 而不是默认值

cocoa-touch - 当我们可以写[NSString new]时,为什么我们有[NSString string]?

java - 如何在Java中实现链表?

ios - 如何更改状态栏的背景颜色而不是导航栏的背景颜色?

ios - 如何在 iOS 中加密文件名和文件夹名?

ios - NSOperation + NSURLConnection

c - 我想知道指针 p 是如何分配给 str 的地址的