i don’t want to write a code like “myview.timer invalidate” before [myview release].
but if the timer is working, i can’t release myview, because timer retain myview.
how can i do?
i want to make the class”myview” simple, just call [myview init] and [myview release]
myview.h
@interface MyView : UIView {
NSString *str;
NSTimer *timer;
}
@property(nonatomic, retain) NSString *str;
@property(nonatomic, assign) NSTimer *timer;
- (void)start;
- (void)doAction;
@end
myview.m
@implementation MyView
@synthesize str, timer;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
NSString *_str = [[NSString alloc] initWithFormat:@"Timer is Running!!! Not Release"];
self.str = _str;
[_str release];
}
return self;
}
- (void)start {
NSTimer *_timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(doAction) userInfo:nil repeats:YES];
self.timer = _timer;
}
- (void)doAction {
NSLog(@"%@",self.str);
}
- (void)dealloc {
[str release];
[timer invalidate];
timer = nil;
[super dealloc];
}
contrllor.m
- (void)viewDidLoad {
MyView *my_view = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
self.myView = my_view;
[my_view release];
[myView start];
[self.view addSubview:myView];
[super viewDidLoad];
}
- (IBAction)releaseMyView {
[myView removeFromSuperview];
[myView release];
}
Repetitive timer retains its target. So if you use repetitive timer then you must invalidate it, and the place to invalidate must not be
dealloc.deallocwon’t be called unless you invalidate the timer. That’s the wayNSTimeris designed. As you have astartmethod, you can write astopmethod which will invalidate the timer, if you are looking for more readable code. The logic is simple: you need to stop if you have started.Another option is instead of
selfyou can use a different object as the target of the timer. Then you can invalidate the timer indealloc. But probably this is not worth the effort.