我使用下面的代码来停止NSTimer
-(void)stopTimer:(NSTimer*)timer;
{
if(!timer) return;
if([timer isValid])
{
[timer invalidate];
timer = nil;
}
}
有时会导致“EXC访问不良”
有时我得到
-[__NSCFType isValid]: unrecognized selector sent to instance 0x6298eb0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType isValid]: unrecognized selector sent to instance 0x6298eb0'
我认为我的代码已检查NSTimer是否有效,如果确定则执行'invalidate'
欢迎任何评论
答案 0 :(得分:2)
如果您在其他地方使计时器无效,则会发生这种情况
确保定时器被释放或无效的任何地方指向它的指针为
您还可以添加第二次检查
if ([timer isKindOfClass:[NSTimer class]])
答案 1 :(得分:0)
我怀疑你过度释放你的计时器变量。
删除timer = nil;
行,看看会发生什么。
invalidate
文档说:
此方法是从NSRunLoop中删除计时器的唯一方法 宾语。 NSRunLoop对象也会删除和释放计时器 就在invalidate方法返回之前或之后的某个时刻。
如果配置了目标和用户信息对象,则为接收者 也释放对这些对象的引用。
答案 2 :(得分:0)
NSTimer
应该是ivar
或属性。保留属性是最简单的,因为保留/释放由@synthesized访问器方法控制。由于该类现在引用了NSTimer指针,因此无需将计时器作为参数传递。这可以实现这样的事情。在.h:
@property (strong, nonatomic) NSTimer *timer;
in .m:
@synthesize timer = _timer;
-(void)stopTimer{
[self.timer invalidate];
self.timer = nil;
}
-(void)startTimer{
[self stopTimer];
self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerTarget) userInfo:nil repeats:YES];
}
您的方法导致崩溃的可能原因是您正在向其传递垃圾指针。指向错误类的有效对象的指针,或指向已回收内存的解除分配对象的指针。
请注意,除非指针(在本例中为计时器)已设置为nil,否则指向已解除分配对象的指针将通过(!timer)
检查。
答案 3 :(得分:0)
如果计时器在任何时候使自身无效(即它不重复),则将其从运行循环中移除并释放。如果您不自行保留,则会被取消分配。在解除分配的对象上调用方法会导致崩溃。
要解决此问题,您可以使用弱引用。
__weak NSTimer *timer;
或
@property (weak, nonatomic) NSTimer *timer;
这使得如果计时器在任何时候被解除分配,它也被设置为nil。