ios 关于使用异步网络请求时block回调的内存注意
2015-09-11 16:41
555 查看
在一个controller中,使用
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
。。。。。。。。。
}];
网络方法请求网络内容,如果在block中,使用了self,或者仅仅使用了类的成员变量,那么这个controller对象就不会被释放!直到这个block的运行结束。这里需要另外特别强调的是,如果你在这个block中使用了nstimer中的scheduledTimerWithTimeInterval延时函数,那么延时调用的函数要负责处理self的引用,block的强引用不会在延时调用函数中继续起作用,比如下面的例子:
当在test函数中调用传过去的self时,是没问题的,因为系统把userInfo这个函数做了强引用。
另外如果仅仅这样写,是不会调用timer的
因为这是个子线程,而它没有runloop run 进行消息循环,所以当函数结束,线程就结束,就没机会调用timer中的函数了。
也可以用下面这种技巧进行延时调用
由于这里的repeat是NO,这个timer结束后,整个runloop就没有事件源了,[[NSRunLoop currentRunLoop] run];函数就会立即返回,继续向下执行!
但是如果使用
这种block格式的调用就没事,因为又用到了block,而新的block又会保留self的强引用。
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
。。。。。。。。。
}];
网络方法请求网络内容,如果在block中,使用了self,或者仅仅使用了类的成员变量,那么这个controller对象就不会被释放!直到这个block的运行结束。这里需要另外特别强调的是,如果你在这个block中使用了nstimer中的scheduledTimerWithTimeInterval延时函数,那么延时调用的函数要负责处理self的引用,block的强引用不会在延时调用函数中继续起作用,比如下面的例子:
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 ]; }); }];
当在test函数中调用传过去的self时,是没问题的,因为系统把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];函数就会立即返回,继续向下执行!
但是如果使用
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIView *view = self.view; NSLog(@"view is %@",view); });
这种block格式的调用就没事,因为又用到了block,而新的block又会保留self的强引用。
相关文章推荐
- Linux中TCP连接过程状态简介
- CS中网络相关的期刊及会议
- CentOS搭建本地yum源(http方式)
- webim如何使用http长轮询保证消息的绝对实时性
- HTTP协议是无状态协议无链接,怎么理解?
- asp.net 后台 Http POST请求
- httpclient4.3 设置代理请求
- 关于HTTP的GET请求参数长度限制问题和我对中国式教育的吐槽
- 使用HttpClient访问网络
- 转 http://www.5icool.org/a/201106/a654.html CSS开发中常用的公用样式
- 携程App的网络性能优化实践
- 获取网络图片
- android:异步加载网络资源
- Apache HTTP Server 与 Tomcat 的三种连接方式介绍
- HttpClient4.4 模仿登陆及维持同一session 请求
- 网络技术之——网络连接URLConnection、单/多线程下载
- HTTPClient4.3的典型小例子
- ajax详细解读
- NFS(网络文件系统) Linux 系统上常用的文件共享方式
- iOS开发网络篇之文件下载、大文件下载、断点下载