[英]UIView subclass not being deallocated
I have a subclassed UIView which is not being deallocated. 我有一个子类的UIView,它不会被释放。 I know that only one class is creating an instance of my view. 我知道只有一个类正在创建我的视图的实例。 I have an NSTimer ivar in my view. 我认为我有一个NSTimer ivar。 If I comment out that timer and when I tap a cancel button that is on this view controller, dealloc in this view is called. 如果我注释掉该计时器,并且当我点击该视图控制器上的取消按钮时,将调用该视图中的dealloc。 If I don't comment out the timer, the dealloc is never called. 如果我不注释掉计时器,则永远不会调用dealloc。
//CustomUIView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_pollTimer = [[NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES] retain];
}
}
I want to keep a reference to this timer because there are times when I wish to pause the timer. 我想保留对此计时器的引用,因为有时候我想暂停计时器。 Now, I could have a property on my view for the timer and in the dealloc method of the class that has a reference to my custom uiview, I could invalidate it before releasing said view. 现在,我可以在计时器的视图上有一个属性,并且在引用了自定义uiview的类的dealloc方法中,可以在释放该视图之前使它无效。 I don't really like this approach because I don't want to expose this timer to outside entities. 我真的不喜欢这种方法,因为我不想将此计时器暴露给外部实体。
Anyone have any ideas? 有人有想法么?
NSTimer
always retains its target . NSTimer
始终保留其目标 。 This has two implications: 这有两个含义:
You shouldn't have the view (which is the timer's target) retain the timer, as this will create a cycle. 您不应该保留视图(这是计时器的目标)来保留计时器,因为这将创建一个循环。
Your view will never be deallocated so long as the timer remains active. 只要计时器保持活动状态,您的视图就永远不会被释放。
Instead, you should call invalidate
on the timer whenever your view is done with it. 取而代之的是,每当完成视图时,都应在计时器上调用invalidate
。 Once this is done, the view will be dealloc
ated when its reference count goes to zero. 一旦做到这一点,认为将dealloc
时,其引用计数为零ated。
Typically this happens when a view is removed from its superview; 通常,将视图从其超级视图中删除时会发生这种情况。 if you want it to keep using its timer until that happens and then get released, you can override removeFromSuperview
to invalidate the timer and then call super
. 如果您希望它一直使用它的计时器直到发生然后释放,您可以重写removeFromSuperview
来使计时器无效,然后调用super
。
You should not retain the timer. 您不应该保留计时器。 Schedule the timer like this : _pollTimer = [NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES];
像这样安排计时器: _pollTimer = [NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES];
and whenever you want to invalidate it: [_pollTimer invalidate]
以及每当您要使其无效时: [_pollTimer invalidate]
In your -dealloc
method, try this: 在您的-dealloc
方法中,尝试执行以下操作:
- (void) dealloc
{
[_pollTimer invalidate];
/*
If not using ARC:
[_pollTimer release], _pollTimer = nil;
[super dealloc];
*/
}
You have forgotten to call super
's implementation of -initWithFrame:
! 您忘记了调用super
的-initWithFrame:
实现-initWithFrame:
! Whoops! 哎呦!
- (id) initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
_pollTimer = [[NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES] retain];
}
return self;
}
This should work much better. 这应该工作得更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.