UIView子类未被释放

时间:2012-06-24 02:11:34

标签: ios uiview nstimer objective-c-2.0

我有一个未被解除分配的子类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,我可以在释放所述视图之前使其无效。我真的不喜欢这种方法,因为我不想将这个计时器暴露给外部实体。

有人有什么想法吗?

3 个答案:

答案 0 :(得分:6)

NSTimer always retains its target。这有两个含义:

  1. 你不应该让视图(这是计时器的目标)保留计时器,因为这将创建一个循环。

  2. 只要计时器保持有效,您的视图就不会被取消分配。

  3. 相反,只要您的视图完成,就应该在计时器上调用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;
}

这应该会好得多。