Objective-C指针? [英] Objective-C pointers?

查看:75
本文介绍了Objective-C指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编码的新手,并试图跟上Objective-C的步伐. 遇到一些我不理解的代码.我希望有人可以 为我澄清一下.在以下情况下,我不确定* foo2的工作方式以及为什么不将其释放?

I am new to coding and trying to get up to speed with Objective-C. Came across some code I did not understand. I was hoping someone could clarify it for me. In the case below, I am not sure how *foo2 is working and why it is not being released?

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可可,我们正在使用半自动引用计数内存管理.为对象分配内存,保留对象或在对象上调用copy方法时,保留计数(引用计数)加1.在对象上调用release时,保留计数减1.在对象上调用autorelease时,将来会在某个时候在该对象上调用release(在主运行循环中,当您自己的代码都没有执行时,因此不会从中提取引用)在您尝试使用它时).当保留计数达到0时,可以释放该对象.

With Objective-C Cocoa, we're working with semi-automatic reference-counting memory management. When allocating memory for an object, retaining an object, or calling a copy method on an object, the retain count (reference count) increments by 1. When calling release on an object, it decrements the retain count by one. When calling autorelease on an object, release will be called on the object at some point in the future (during the main run loop, when none of your own code is executing, so it won't pull the reference out from under you as you're trying to use it). When the retain count reaches 0, the object can be deallocated.

通常,如果要在对象上调用retain,则表示对它有兴趣,并且您有责任在不存在对象的某个时候进行releaseautorelease调用对对象不再感兴趣.同样,如果在对象上调用alloccopy方法,则表明您对该对象感兴趣,并且必须将该对象与releaseautorelease匹配.

In general, if you're calling retain on an object, you're signalling your interest in it, and you are responsible for making a release or autorelease call at some point when you're no longer interested in the object. Likewise, if you call alloc or a copy method on an object, you have signalled your interest in the object and must match it with a release or autorelease somewhere down the line.

此链接几乎涵盖了Apple使用(并且应该使用)内存管理的准则:可可中内存管理的简单规则

This link pretty much covers the guidelines Apple uses (and you should use) for memory management: Simple rules for memory management in Cocoa

让我们逐行浏览代码:

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

pointer指向新分配的ClassOne对象,其保留计数为1,因为我们在其上调用了alloc.我们有责任在将来的某个时间在pointer上调用releaseautorelease.

pointer points to a newly allocated ClassOne object, with a retain count of 1, since we called alloc on it. We have a responsibility to call release or autorelease on pointer at some point in the future.

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

foo指向新分配的ClassTwo对象,其保留计数为1,因为我们在其上调用了alloc.我们有责任在将来某个时候在foo上调用releaseautorelease.

foo points to a newly allocated ClassTwo object, with a retain count of 1, since we called alloc on it. We have a responsibility to call release or autorelease on foo at some point in the future.

foo2现在没有特别指出.使用不安全.

foo2 doesn't point to anything in particular right now. It's not safe to use.

foo2 = [foo add: pointer];

pointer已添加到foo(无论什么意思;我们不知道其实现). foo可能在pointer上调用了retain以表示它对此感兴趣,并将其添加为字段,或者它可能已将pointer添加到集合中(在这种情况下,调用retain是集合的责任>(添加对象时在其上),release(移除对象时).无论如何,它都不会影响我们的代码块,因此我们不在乎引擎盖下发生了什么

pointer has been added to foo (whatever that means; we don't know the implementation). foo might have called retain on pointer to signal its interest in it, and added it as a field, or it might have added pointer to a collection (in which case it's the collection's responsibility to call retain on it when an object is added, and release when an object is removed). In any case, it doesn't affect our code block, so we don't care what's going on under the hood

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

The reference returned by this method might be pointer itself, or it might be an autoreleased copy of pointer; we don't have access to the API or the implementation to tell us which.

在任何一种情况下,在此对象上调用release都不是我们的责任.如果该方法的名称中有copy,或者如果我们在返回的引用中调用了retain(例如foo2 = [[foo add:pointer] retain];),则保留计数将增加1,这是我们的责任releaseautorelease.

In either case, it is not our responsibility to call release on this object. If the method had copy in the name, or if we had called retain on the returned reference (like foo2 = [[foo add:pointer] retain];), then the retain count would have been incremented by 1, and it would have been our responsibility to call release or autorelease on it.

[foo release];

foo引用的对象已释放,这意味着其保留计数已减少1.对于本示例,此对象与我们在第2行进行的alloc调用配对,因此保留计数将降至0 ,从而可以释放foo.

The object referenced by foo has been released, meaning its retain count has been decremented by 1. For this example, this pairs with the alloc call we made in line 2, so the retain count will drop to 0, making foo eligible to be freed.

但是,一般来说,我们并不关心对象是否已被释放.我们只需要确保将所有alloccopyretain呼叫与相同数量的releaseautorelease呼叫配对即可.如果我们随时在某个对象中注册了兴趣,则有责任释放我们的兴趣,否则我们将发生内存泄漏.

In general, though, we don't care if the object has been deallocated or not; we just need to make sure we pair up any alloc, copy, or retain calls with the same number of release or autorelease calls. If we register an interest in an object at any time, it's our responsibility to release our interest, otherwise we'll have memory leaks.

 foo = foo2;

foo现在指向foo2引用的同一对象.记住,当我们得到foo2时,我们没有调用alloccopy方法,也没有通过调用retain来注册它的兴趣.由于我们没有责任在foo2上调用release,因此我们没有责任在foo上调用release.

foo now points to the same object referenced by foo2. Remember, we haven't called an alloc or copy method when we got foo2, nor did we register an interest in it by calling retain. Since we don't have a responsibility to call release on foo2, we don't have a responsibility to call release on foo.

[pointer release];

pointer的保留计数减少了1.这可能使它的保留计数为0,这取决于foo在添加它时的处理方式.不过,我们不在乎;我们已经完成对pointer的责任,方法是在其上调用release使其与开始时的alloc调用相匹配.尽管pointer可能在此调用之后仍然存在,但是我们无法做出这样的假设,并且尝试对指针之前引用的对象进行任何操作都是一个错误(尽管我们可以随意更改pointer来指向其他内容) ).

pointer's retain count has been decremented by 1. This may have brought its retain count to 0 or not, it depends on what foo did with it when we added it. Still, we don't care; we have finished our responsibility to pointer by calling release on it to match with the alloc call we made at the beginning. Although pointer might still be around after this call, we can't make that assumption, and trying to do anything with the object previously referenced by pointer would be a mistake (though we could change pointer to point at something else freely).

[foo release];

如果此代码的作者一直遵循Apple的内存管理约定,那么这是不必要的.我们没有责任在foofoo2上调用release(记住,它们指向同一个对象).这不会导致代码中断;在nil引用上调用任何内容本质上都是无操作的.但是,这可能会给审查代码的人造成混乱.

If the author of this code has been following Apple's memory management conventions, then this is unnecessary. We don't have a responsibility to call release on foo or foo2 (they point to the same object, remember). This won't cause the code to break; calling anything on a nil reference is essentially a no-op. However, it may cause confusion for anyone reviewing the code.

现在,此代码的作者可能已经破坏了内存管理约定.他可能已经使add调用返回了pointer的副本而没有在其上调用autorelease,在这种情况下,它使调用方负责在其上调用release.这是一种非常糟糕的形式,如果您遇到破坏内存管理约定的代码,请记录下使用的地方以及如何打破约定以避免将来的混乱.

Now, the author of this code may have broken the memory management conventions. He might have made that add call return a copy of pointer without calling autorelease on it, in which case it makes the caller responsible for calling release on it. This is very bad form, and if you should run into code which breaks the memory management convention, document where you use it and how it breaks the convention to avoid confusion in the future.

这篇关于Objective-C指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆