I have some problem to design my program which need to release an object in its delegate method. My main class (View controller in my case) holds a lot of tasks ( which represented by Task class) in a NSMutableDictionary. When task ends, it will call its delegate method in main class. Then the Task object will be remove from NSMutableDictionary. The reason why I remove the Task object in the delegate method is because I need to add/remove Task object dynamically. The problem is after I remove the Task object from NSMutableDictionary, it'll be released. But it has to return to the place of Task object call the delegate method. At this point, the Task object has been release already. It of course will cause crash.
Please refer to my code, it will explain my situation more clearly:
Code:
//////// main class (view controller)
_allTasks = [[NSMutableDictionary alloc]init];
// You have to make sure the task name unique
Task* task1 = [[Task alloc]initWithDelay:10];
task1.name = @"Task1";
task1.delegate = self;
[_allTasks setObject:task1 forKey:task1.name];
[task1 start];
[task1 release];
-(void)onTaskFinished:(Task*)task
{
[_allTasks removeObjectForKey:task.name];
}
//// Task.h
#import <Foundation/Foundation.h>
@class Task;
@protocol TaskDelegate <NSObject>
-(void)onTaskFinished:(Task*)task;
@end
@interface Task : NSObject {
id<TaskDelegate> _delegate;
NSUInteger _delay;
NSString* _name;
}
@property (nonatomic,assign) id delegate;
@property (nonatomic,retain) NSString* name;
-(id)initWithDelay:(NSUInteger)second;
-(void)start;
@end
/////// Task.m ///////////
#import "Task.h"
@implementation Task
@synthesize delegate = _delegate;
@synthesize name = _name;
-(id)initWithDelay:(NSUInteger)second
{
if ( self == [super init] )
{
_delay = second;
}
return self;
}
-(void)start
{
[NSTimer scheduledTimerWithTimeInterval:_delay target:self selector:@selector(onTimer:) userInfo:nil repeats:0];
[self release];
}
-(void)onTimer:(NSTimer*)theTimer
{
[theTimer invalidate];
[_delegate performSelector:@selector(onTaskFinished:) withObject:self];
}
-(void)dealloc
{
[super dealloc];
self.delegate = nil;
[self.name release];
}
@end
Please note, there is a [self release] in my start method. That is I purposely added to mimic my real situation (the [NSTimer scheduledTimerWithTimeInterval] will increase my retain count probably because of the target parameter.
Can anybody advise what I should to handle this kind of problem? Thank you so much