我有一个未被解除分配的子类UIView。我知道只有一个类正在创建我的视图实例。我认为我有一个NSTimer ivar。如果我注释掉该计时器,当我点击此视图控制器上的取消按钮时,将调用此视图中的dealloc。如果我没有注释掉计时器,则永远不会调用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];
}
}
我想保留对此计时器的引用,因为有时我希望暂停计时器。现在,我可以在我的计时器视图上有一个属性,并且在类的dealloc方法中引用了我的自定义uiview,我可以在释放所述视图之前使其无效。我真的不喜欢这种方法,因为我不想将这个计时器暴露给外部实体。
有人有什么想法吗?
答案 0 :(得分:6)
NSTimer
always retains its target。这有两个含义:
你不应该让视图(这是计时器的目标)保留计时器,因为这将创建一个循环。
只要计时器保持有效,您的视图就不会被取消分配。
相反,只要您的视图完成,就应该在计时器上调用invalidate
。完成此操作后,当引用计数变为零时,视图将为dealloc
。
通常,当从其超级视图中删除视图时会发生这种情况;如果你希望它继续使用它的计时器直到发生这种情况然后被释放,你可以覆盖removeFromSuperview
以使计时器无效,然后调用super
。
答案 1 :(得分:1)
您不应该保留计时器。安排计时器如下:_pollTimer = [NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES];
以及每当您想要使其无效时:[_pollTimer invalidate]
答案 2 :(得分:0)
在-dealloc
方法中,试试这个:
- (void) dealloc
{
[_pollTimer invalidate];
/*
If not using ARC:
[_pollTimer release], _pollTimer = nil;
[super dealloc];
*/
}
您忘记致电super
-initWithFrame:
的实施!糟糕!
- (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;
}
这应该会好得多。