NSTimer 禁用 UIView 中的 dealloc

发布于 2024-11-01 02:07:35 字数 521 浏览 0 评论 0原文

@interface someview:UIView{
  NSTimer* timer;
}
@end

@implementation someview

-(void)dealloc{
  NSLog(@"dealloc someview");
  [timer invalidate];
  timer = nil;
}
-(void)runTimer{
//
}
-(void)someMethod{

  timer = [NSTimer timerWithTimeInterval:2.0f target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
}

@end

释放 someview 不会调用 dealloc 并且计时器继续运行。

如果我注释掉“timer = [NSTimer Schedule....”部分,则将调用 dealloc。这意味着我的代码的所有其他部分都工作正常,而计时器是罪魁祸首。 runTimer 方法是空的,这意味着它只是计时器在搞乱我。

@interface someview:UIView{
  NSTimer* timer;
}
@end

@implementation someview

-(void)dealloc{
  NSLog(@"dealloc someview");
  [timer invalidate];
  timer = nil;
}
-(void)runTimer{
//
}
-(void)someMethod{

  timer = [NSTimer timerWithTimeInterval:2.0f target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
}

@end

Releasing someview will NOT call dealloc and the timer keeps on running.

If I comment out the "timer = [NSTimer schedule...." part, dealloc will be called. Which means all the other part of my code is working properly and the timer is the culprit. The runTimer method is empty, which means it's just the timer messing with me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空‖城人不在 2024-11-08 02:07:35

我认为在 UIView 内部使用 NSTimer 时最好的解决方案是重写 removeFromSuperview 方法;

- (void)removeFromSuperview
{
    [timer invalidate];
    timer = nil;

    [super removeFromSuperview];
}

这里唯一要记住的是,您需要确保计时器不是一个 nil 对象,因为 removeFromSuperview 也可以从其他 UIView 的 super dealloc 方法自动调用。您可以包裹一个条件来检查。

I think the best solution when using an NSTimer inside of a UIView is to override the removeFromSuperview method;

- (void)removeFromSuperview
{
    [timer invalidate];
    timer = nil;

    [super removeFromSuperview];
}

The only thing to keep in mind here is that you need to ensure that timer is not a nil object because removeFromSuperview can also get automatically called from other UIView's super dealloc methods. You could wrap in a conditional to check.

放赐 2024-11-08 02:07:35

NSTimer 保留目标。因此,在视图被释放之前,计时器必须失效。

NSTimer retains the target. Therefore, the timer must be invalidated before your view is dealloc'd.

携君以终年 2024-11-08 02:07:35

如上所述,计时器保留其目标。在定时器失效之前,定时器和视图之间存在一个保留周期,因此视图不会被释放。

当通过子类化didMoveToSuperview从视图层次结构中删除计时器时,我将使计时器无效,当存在与视图相关的更改(例如超级视图更改)时,系统会调用它。仅当在 UIView 上调用 removeFromSuperview 时才会调用“removeFromSuperview”

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];

    if (!self.superview)
    {
        [timer invalidate];
        timer = nil;
    }
}

As mentioned above, Timers retain their targets. Until the timer is invalidated, there is a retain cycle between the timer and the view, so the view will not be deallocated.

I would invalidate the timer when it's removed from the view hierarchy by subclassing didMoveToSuperview, this gets called by the system when there is a View-Related Change (e.g superview changes). The 'removeFromSuperview' is only called when removeFromSuperview is called on UIView

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];

    if (!self.superview)
    {
        [timer invalidate];
        timer = nil;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文