RetainCount可以在这种情况下使用吗? [英] RetainCount OK to use in this instance?

查看:108
本文介绍了RetainCount可以在这种情况下使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

retainCount是禁忌,不可靠,不可预测,通常不应该使用.我不在代码中的任何地方使用它,但是我在一个有趣的方式使用的一个类中看到了它.

retainCount is taboo, unreliable, unpredictable, and in general shouldn't be used. I don't use it anywhere in my code, but I have seen it in one class that I use in an interesting way.

我有一个类,它运行一个无限期运行的线程,直到该线程被取消为止.问题是线程增加了所有者的保留数,在我的例子中,是实例化它的类.因此,即使我已经完成了该类的使用,该实例仍然会徘徊,除非管理我的类的人也知道要关闭线程.那是一种解决方案,但这就是我在代码中找到的.

I have a class that runs a thread that runs indefinitely until the thread is cancelled. The catch is that the thread increases the retain count of the owner, in my case the class that instantiated it. So, even if I am done using that class, that instance is still going to hang around unless whoever is managing my class also has the smarts to know to shut down the thread. That is one solution, but this is what I found in code.

- (oneway void)release
{
    // This override allows allows this object to be dealloced 
    // by shutting down the thread when the thread holds the last reference.
    // Otherwise, the object will never be dealloc'd
    if (self.retainCount == 2)
    {
        [self quitDispatchThread];
    }

    [super release];
}

这是一个聪明的解决方案,但是我不确定该怎么看.它会覆盖类上的release,并检查保留计数是否为2.换句话说,它检查是否只有线程使我的对象保持活动状态(因为保留计数大约是2). (从2减到1),如果是,它将终止线程(quitDispatchThread将阻塞直到线程终止).

This is a clever solution, but I'm not sure what to think of it. It overrides release on the class and checks to see if the retain count is 2. In other words, it checks to see if the thread is the only thing keeping my object alive (since the retain count is about to be decremented from 2 to 1) and if it is, it terminates the thread (quitDispatchThread will block until the thread is terminated).

所以...

通常人们说要远离retainCount,因为您不知道其中是否有一些自动发行版.但是,如果keepCount为1,那么我就知道一个事实,只有线程使它保持活动状态,而且我不必担心由于某些自动释放等原因,retainCount可能会关闭.

Usually people say to stay clear of retainCount because you don't know if there are some autoreleases in there. However, if the retainCount is one then I know for a fact that only the thread is keeping it alive and I don't have to be concerned that the retainCount might be off due to some autoreleases, etc...

我打算将其删除,但实际上似乎是有道理的.其他对象不必知道我的类正在运行线程.其他对象可以安全地retainrelease甚至autorelease拥有线程的对象,而不必担心因为自己照顾线程而关闭线程.

I was about to remove it, but it actually seems to make sense. Other objects don't have to have an awareness that my class is running a thread. Other objects can safely retain and release or even autorelease the object owning the thread without having to worry about shutting the thread down because it takes care of itself.

这段代码实际上感觉很干净,这让我感到惊讶.

This code actually feels clean, which surprises me.

我使用NSThread的事实增加了对象的保留计数.我的对象是target,而selector是线程在其上运行的方法.

The retain count of my object is increased by the fact I'm using NSThread. My object is the target and the selector is the method the thread runs on.

initWithTarget:selector:object:

返回使用给定参数初始化的NSThread对象.

Returns an NSThread object initialized with the given arguments.

  • (id)initWithTarget:(id)目标选择器:(SEL)选择器对象:(id)参数

参数

目标

选择器指定的消息发送到的对象.

The object to which the message specified by selector is sent.

选择器

要发送到目标的消息的选择器.该选择器必须 仅接受一个参数,并且不得具有返回值.

The selector for the message to send to target. This selector must take only one argument and must not have a return value.

参数

传递给目标的单个参数.可能为零.

The single argument passed to the target. May be nil.

返回值

使用给定参数初始化的NSThread对象.

An NSThread object initialized with the given arguments.

讨论

对于非垃圾收集应用程序,方法选择器为 负责为新分离的成员设置自动释放池 线程并在退出之前释放该池.垃圾收集 应用程序不需要创建自动释放池.

For non garbage-collected applications, the method selector is responsible for setting up an autorelease pool for the newly detached thread and freeing that pool before it exits. Garbage-collected applications do not need to create an autorelease pool.

对象目标和参数在执行分离线程期间会保留.当线程最终释放时,它们被释放 退出.

The objects target and argument are retained during the execution of the detached thread. They are released when the thread finally exits.

推荐答案

retainCount是禁忌,不可靠,不可预测,通常不应该使用.

retainCount is taboo, unreliable, unpredictable, and in general shouldn't be used.

您可以依赖retainCount的值,前提是您的对象不会通过任何对您来说不透明的代码,例如任何Cocoa框架.实际上,这几乎是不可能实现的,因此是警告.可可的内部可能会多次,出于多种原因将对象传递,保留,释放并将其放入自动释放池中,并且您不能在任何给定时间依赖其绝对值.

You can rely on the value of retainCount IFF your objects don't pass through any code that's opaque to you, such as any Cocoa framework. In practice, this is almost impossible to achieve, thus the warning. The internals of Cocoa may be passing your object around, retaining, releasing, and putting it into autorelease pools many times and for many reasons, and you can't rely on its absolute value at any given point.

问题在于线程增加了所有者的保留数,在我的例子中,是实例化它的类.

The catch is that the thread increases the retain count of the owner, in my case the class that instantiated it.

这是一个保留周期.答案是找到一种打破这种循环的方法,而不是颠覆参考计数机制.当您的线程或拥有对象知道线程正在执行的工作已完成(或需要提前停止)时,必须在 释放之前有一点.

That's a retain cycle. The answer here is to find a way to break that cycle, not to subvert the reference counting mechanism. There must be some point before deallocation when either your thread or the owning object knows that the work the thread is performing is done (or needs to stop prematurely).

听起来,拥有对象是客户端代码与线程正在执行的工作的接口.该拥有对象需要一个立即关闭"方法,该方法需要在 所有者释放它之前被调用(并记录为必须被调用").在这种关闭方法中,您可以通过释放线程来中断周期.

It sounds like the owning object is the interface for client code to the work the thread is doing. This owning object needs a "shutdown now" method that needs to be called (and documented as "must be called") before its owner releases it. In that shutdown method, you can break the cycle by releasing the thread.

我不确定线程​​正在保留其创建者(该循环很清楚地表明某事您的所有权模型有误)是怎么回事–我猜您正在使用NSThreadinitWithTarget:...,目标是创建/拥有对象.这是标准MVC模式的混合体-线程的所有者是控制器",线程本身(以及它运行的代码)更多的是模型".

I'm not exactly sure what's going on that the thread is retaining its creator (the cycle is a pretty clear indication that something is wrong with your ownership model) -- I'd guess you're using NSThread and initWithTarget:..., with the target being the creating/owning object. This is a bit of a mixup of the standard MVC pattern -- the owner of the thread is a "controller", the thread itself (and the code it runs) more of a "model".

换句话说,控制器不应包含线程的代码.我建议您将线程的代码分解到另一个对象中,以用作目标.然后,控制器对象同时拥有线程本身和工作"目标对象,而它们都不拥有控制器.哎呀,没有周期!

The controller should not contain the thread's code, in other words. I'd recommend that you factor out the thread's code into another object to use as the target. Then the controller object owns both the thread itself and the "work" target object, with neither of them owning the controller. Voilà, no cycle!

这篇关于RetainCount可以在这种情况下使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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