gpt4 book ai didi

objective-c - NSTimer 作为 self 定位的 ivar

转载 作者:太空狗 更新时间:2023-10-30 03:49:45 24 4
gpt4 key购买 nike

我遇到了一个尴尬的情况,我想要一个带有 NSTimer 实例变量的类,只要该类还活着,它就会重复调用该类的方法。出于说明目的,它可能看起来像这样:

// .h
@interface MyClock : NSObject {
NSTimer* _myTimer;
}
- (void)timerTick;
@end

-

// .m
@implementation MyClock

- (id)init {
self = [super init];
if (self) {
_myTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerTick) userInfo:nil repeats:NO] retain];
}
return self;
}

- (void)dealloc {
[_myTimer invalidate];
[_myTImer release];
[super dealloc];
}

- (void)timerTick {
// Do something fantastic.
}

@end

这就是我想要的。我不想在我的类上公开一个接口(interface)来启动和停止内部计时器,我只希望它在类存在时运行。看起来很简单。

但问题是 NSTimer 保留了它的目标。这意味着只要该计时器处于事件状态,它就会阻止该类被正常的内存管理方法释放,因为计时器已保留它。手动调整保留计数是不可能的。 NSTimer 的这种行为似乎很难将重复计时器作为 ivar,因为我想不出 ivar 应该保留其所属类的时间。

这让我不得不承担一些不愉快的职责,即想出一些方法在 MyClock 上提供一个接口(interface),允许类的用户控制计时器何时启动和停止。除了增加不必要的复杂性之外,这很烦人,因为让类实例的一个所有者使计时器无效可能会踩到另一个指望它继续运行的所有者的脚趾。我可以实现我自己的伪保留计数系统来保持计时器运行,但是,……真的吗?对于这样一个简单的概念,这是很多工作的方法。

我能想到的任何解决方案都感觉很老套。我最终为 NSTimer 编写了一个包装器,它的行为与普通 NSTimer 完全一样,但不保留其目标。我不喜欢它,如果有任何见解,我将不胜感激。

最佳答案

由计时器引起的保留循环令人头疼。我使用过的最不脆弱的方法是保留计时器,但总是在使它无效时将引用设置为 nil。

@interface Foo : NSObject
{
__weak NSTimer *_timer;
}
@end

@implementation Foo
- (void) foo
{
_timer = [NSTimer ....self....];
}

- (void) reset
{
[_timer invalidate], _timer = nil;
}

- (void) dealloc
{
// since the timer is retaining self, no point in invalidating here because
// that just can't happen
[super dealloc];
}
@end

不过,最重要的是,您必须调用 -reset 才能释放 self。一个解决方案是在 selftimer 之间设置一个代理。代理可以对 self 有一个弱引用,并简单地将定时器触发的调用传递给 self。然后,当 self 被释放时(因为计时器不保留 self 也不保留代理),您可以在 中调用 invalidate >解除分配

或者,如果针对 Mac OS X,请打开 GC 并完全忽略这些废话。

关于objective-c - NSTimer 作为 self 定位的 ivar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4687738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com