Timer循环引用
- (IBAction)onClickCloseVC:(id)sender
{
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)onClickBtn:(id)sender
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(updateFeed:) userInfo:nil repeats:YES];
}
- (void)updateFeed:(id)sender
{
NSLog(@"updateFeed");
}
- (void)dealloc
{
[self.timer invalidate];
NSLog(@"Page4VC dealloc");
}
对象持有定时器
定时器持有对象
运行循环也持有定时器
因为循环引用 dealloc 永远不会被调用
改进1
- (IBAction)onClickCloseVC:(id)sender
{
[self cleanUp];
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)onClickBtn:(id)sender
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(updateFeed:) userInfo:nil repeats:YES];
}
- (void)updateFeed:(id)sender
{
NSLog(@"updateFeed");
}
- (void)dealloc
{
NSLog(@"Page4VC dealloc");
}
//- (void)didMoveToParentViewController:(UIViewController *)parent
//{
// if(parent == nil)
// {
// [self cleanUp];
// }
//}
- (void)cleanUp
{
[self.timer invalidate];
}
改进2
@interface Page4VC ()
@property (nonatomic, strong) FeedUpdateTask *updateTask;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
- (void)viewDidLoad
{
[super viewDidLoad];
self.updateTask = [[FeedUpdateTask alloc] initWithTimeInterval:10 target:self selector:@selector(updateFeed:)];
}
- (IBAction)onClickCloseVC:(id)sender
{
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)onClickBtn:(id)sender
{
}
- (void)updateFeed:(id)sender
{
NSLog(@"updateFeed");
UIImage *image = (UIImage *)sender;
self.imageView.image = image;
}
- (void)dealloc
{
NSLog(@"Page4VC dealloc");
[self.updateTask shutDown];
}
@interface FeedUpdateTask : NSObject
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL selector;
- (instancetype)initWithTimeInterval:(NSTimeInterval)interval target:(id)target selector:(SEL)selector;
- (void)shutDown;
@end
@interface FeedUpdateTask ()
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSURLSessionTask *downloadTask;
@end
@implementation FeedUpdateTask
- (instancetype)initWithTimeInterval:(NSTimeInterval)interval target:(id)target selector:(SEL)selector
{
self = [super init];
if(self)
{
self.target = target;
self.selector = selector;
self.timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(fetchAndUpdate:) userInfo:nil repeats:YES];
}
return self;
}
- (void)fetchAndUpdate:(NSTimer *)timer
{
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__strong typeof(weakSelf) sself = weakSelf;
NSURL *imgURL = [[NSURL alloc] initWithString:@"http://macdown.uranusjr.com/static/images/logo-160.png"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:imgURL];
NSURLSession *session = [NSURLSession sharedSession];
sself.downloadTask = [session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
UIImage *image = [[UIImage alloc] initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
if(!sself)
{
return;
}
if(sself.target == nil)
{
return;
}
id target = sself.target;
SEL selector = sself.selector;
if([target respondsToSelector:selector])
{
[target performSelector:selector withObject:image];
}
});
}];
[sself.downloadTask resume];
});
}
- (void)shutDown
{
[self.downloadTask cancel];
[self.timer invalidate];
self.timer = nil;
}
- (void)dealloc
{
NSLog(@"FeedUpdateTask dealloc");
}
@end
改进3
- (void)viewDidLoad
{
[super viewDidLoad];
self.updateTask = [[FeedUpdateTask alloc] initWithTimeInterval:10];
self.updateTask.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)onClickCloseVC:(id)sender
{
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)onClickBtn:(id)sender
{
[self.updateTask start];
}
- (void)updateFeed:(id)sender
{
NSLog(@"updateFeed");
UIImage *image = (UIImage *)sender;
self.imageView.image = image;
}
- (void)dealloc
{
NSLog(@"Page4VC dealloc");
if(self.updateTask != nil)
{
[self.updateTask shutDown];
}
}
@protocol FeedUpdateTaskDelegate <NSObject>
- (void)updateFeed:(id)sender;
@end
@interface FeedUpdateTask : NSObject
- (instancetype)initWithTimeInterval:(NSTimeInterval)interval;
@property (nonatomic, weak) id<FeedUpdateTaskDelegate> delegate;
- (void)start;
- (void)shutDown;
@end
- (void)start
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.interval target:self selector:@selector(fetchAndUpdate:) userInfo:nil repeats:YES];
}
- (void)fetchAndUpdate:(NSTimer *)timer
{
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__strong typeof(weakSelf) sself = weakSelf;
NSURL *imgURL = [[NSURL alloc] initWithString:@"http://macdown.uranusjr.com/static/images/logo-160.png"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:imgURL];
NSURLSession *session = [NSURLSession sharedSession];
sself.downloadTask = [session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
UIImage *image = [[UIImage alloc] initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
if(!sself)
{
return;
}
id<FeedUpdateTaskDelegate> delegate = sself.delegate;
if(!delegate)
{
}
else
{
[delegate updateFeed:image];
}
});
}];
[sself.downloadTask resume];
});
}
- (void)shutDown
{
[self.downloadTask cancel];
[self.timer invalidate];
self.timer = nil;
self.delegate = nil;
}
- (void)dealloc
{
NSLog(@"FeedUpdateTask dealloc");
}