Objective-C 指针?

标签 objective-c oop pointers

我是编码新手,并试图跟上 Objective-C 的速度。
遇到一些我不明白的代码。我希望有人可以
帮我澄清一下。在下面的情况下,我不确定 *foo2 是如何工作的以及为什么它没有被发布?

ClassOne *pointer = [[ClassOne alloc]init];

ClassTwo *foo = [[ClassTwo alloc]init], *foo2; 

 foo2 = [foo add: pointer];
 [foo release]; 
 foo = foo2

[pointer release];

[foo release];

最佳答案

使用 Objective-C Cocoa,我们正在使用半自动引用计数内存管理。为对象分配内存、保留对象或调用 copy 时对象上的方法,保留计数(引用计数)增加 1。调用时 release在一个对象上,它将保留计数减一。打电话时autorelease在一个物体上,release将在将来的某个时间点在对象上调用(在主运行循环期间,当您自己的代码都没有执行时,因此当您尝试使用它时,它不会从您的下方拉出引用)。当保留计数达到 0 时,可以释放对象。

一般来说,如果您拨打 retain在一个物体上,你表明你对它感兴趣,你有责任制作 releaseautorelease当您不再对对象感兴趣时调用。同样,如果您拨打 alloccopy对象上的方法,您已经表示您对该对象感兴趣,并且必须将其与 release 匹配或 autorelease下线的某个地方。

此链接几乎涵盖了 Apple 使用(您应该使用)的内存管理指南:Simple rules for memory management in Cocoa

让我们逐行浏览代码:

ClassOne *pointer = [[ClassOne alloc]init];

pointer指向一个新分配的 ClassOne 对象,保留计数为 1,因为我们对其调用了 alloc。我们有责任拨打releaseautoreleasepointer在 future 的某个时候。

ClassTwo *foo = [[ClassTwo alloc]init], *foo2;

foo指向一个新分配的 ClassTwo 对象,保留计数为 1,因为我们对其调用了 alloc。我们有责任拨打releaseautoreleasefoo在 future 的某个时候。
foo2现在没有特别指向任何东西。使用起来并不安全。

foo2 = [foo add: pointer];

pointer已添加到 foo (不管这意味着什么;我们不知道实现)。 foo可能打过电话 retainpointer表明它对它感兴趣,并将其添加为一个字段,或者它可能添加了 pointer到一个集合(在这种情况下,集合有责任在添加对象时调用 retain,删除对象时调用 release)。在任何情况下,它都不会影响我们的代码块,所以我们不关心引擎盖下发生了什么

此方法返回的引用可能是 pointer本身,或者它可能是 pointer 的自动发布副本;我们无权访问 API 或实现来告诉我们哪个。

无论哪种情况,我们都没有责任拨打 release在这个对象上。如果方法有 copy在名称中,或者如果我们调用 retain在返回的引用(如 foo2 = [[foo add:pointer] retain]; )上,保留计数将增加 1,我们有责任调用 releaseautorelease就可以了。

[foo release];

foo 引用的对象已被释放,这意味着它的保留计数已减 1。在本例中,它与 alloc 配对。我们在第 2 行调用,因此保留计数将下降到 0,使 foo有资格被释放。

不过,一般来说,我们并不关心对象是否已被释放;我们只需要确保我们配对任何 alloc , copy , 或 retainrelease 相同号码的调用或 autorelease调用。如果我们在任何时候注册一个对象的兴趣,释放我们的兴趣是我们的责任,否则我们将有内存泄漏。

 foo = foo2;

foo现在指向由 foo2 引用的同一个对象.请记住,我们还没有拨打过 alloccopy当我们得到 foo2 时的方法,我们也没有通过拨打 retain 来登记对它的兴趣。 .由于我们没有责任拨打releasefoo2 ,我们没有责任拨打releasefoo .

[pointer release];

pointer的保留计数已减 1。这可能使其保留计数为 0 或不为 0,这取决于 foo当我们添加它时就这样做了。不过,我们不在乎;我们已经完成了对pointer的责任调用 release就可以与alloc相匹配我们一开始打的电话。虽然 pointer在这个调用之后可能仍然存在,我们不能做出这个假设,并且试图对之前由指针引用的对象做任何事情都是错误的(尽管我们可以改变 pointer 以自由地指向其他东西)。

[foo release];


如果这段代码的作者一直遵循 Apple 的内存管理约定,那么这是不必要的。我们没有责任拨打releasefoofoo2 (它们指向同一个对象,记住)。这不会导致代码中断;在 nil 上调用任何东西引用本质上是一个空操作。但是,它可能会导致任何查看代码的人感到困惑。

现在,这段代码的作者可能已经打破了内存管理约定。他可能已经做到了add调用返回 pointer 的副本无需调用 autorelease在它上面,在这种情况下,它让调用者负责调用 release就可以了。这是非常糟糕的形式,如果您遇到违反内存管理约定的代码,请记录您使用它的位置以及它如何违反约定以避免将来混淆。

关于Objective-C 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/529482/

相关文章:

php - 无法通过另一个类连接到数据库

C++ : function gets pointer or refernce

c - 指针数组与跳过列表混淆

php - PHP-检测另一个对象上的更改

c++在不知道对象类型的情况下定义成员函数指针

objective-c - 使用 ReactiveCocoa 触发模型持久化有意义吗

ios - 在 Objective-c 问题中访问委托(delegate)静态方法

iphone - 当 UIButton 内容模式为 "center,"时背景图像被像素化

ios - UITableView didSelectRow 在错误的 Cell 上执行,即使 touchesCancelled 调用了包含自定义 UIScrollView 的自定义 UITableViewCell

design-patterns - 干燥与 "prefer containment over inheritance"