ios NSTimer的强引用问题

在一个controller中,使用

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

 

    }];

网络方法请求网络内容,如果在block中,使用了self,或者仅仅使用了类的成员变量,那么这个controller对象就不会被释放!

比如下面的例子:

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{ 
[NSTimer scheduledTimerWithTimeInterval:2.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO  ]; 
});

}];

系统把userInfo这个参数做了强引用。


 

另外如果仅仅这样写,是不会调用timer的

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"1111");
 
            [NSTimer scheduledTimerWithTimeInterval:4.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO];   
    }];

 

因为这是个子线程,而它没有runloop run 进行消息循环,所以当函数结束,线程就结束,就没机会调用timer中的函数了。


 

 

也可以用下面这种技巧进行延时调用

 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"1111");
            [NSTimer scheduledTimerWithTimeInterval:4.0 target:[UIApplication sharedApplication].delegate selector:@selector(test:) userInfo:self repeats:NO];
        [[NSRunLoop currentRunLoop] run];        
    
    }];

由于这里的repeat是NO,这个timer结束后,整个runloop就没有事件源了,[[NSRunLoop currentRunLoop] run];函数就会立即返回,继续向下执行!

 

posted @ 2015-09-11 16:41  幻化成疯  阅读(494)  评论(0编辑  收藏  举报